List 无冲突/2

List 无冲突/2,list,prolog,List,Prolog,我正在尝试编写一个程序,该程序包含包和版本的列表。如果候选集中没有冲突的版本,则应为真。也就是说,如果没有列出具有不同版本的包 ?- conflict_free([cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.3']). true. ?- conflict_free([cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.0']). false. ?- conflict_free([gfortran, gcc, li

我正在尝试编写一个程序,该程序包含包和版本的列表。如果候选集中没有冲突的版本,则应为真。也就是说,如果没有列出具有不同版本的包

?- conflict_free([cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.3']).
true.

?- conflict_free([cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.0']).
false.

?- conflict_free([gfortran, gcc, libc6, libc6], ['4.4.3', '4.4.3', '2.11.1', '2.11.1']).
true.

?- conflict_free([gfortran, gcc, libc6, libc6], ['4.4.3', '4.4.3', '2.11.1', '2.7.3']).
false.
我尝试使用position/4查找重复元素的索引,其行为如下:

?- positions([a, b, c, b, c, a, d, b, c], b, Posn, 0).
Posn = [1, 3, 7].

?- positions([cython, gcc, gcc], gcc, Posn, 0).
Posn = [1, 2].
我尝试递归地使用
position/4
检查是否有返回
Posn
为>=
2
,然后尝试使用版本列表中的索引,看看是否有任何不同的版本。但这对我不起作用


有什么建议吗?

首先,让我们将列表
zip
组合成一个成对的列表:

?- pairs_keys_values(PkgVer, [cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.3']).
PkgVer = [cython-'0.11.2', gcc-'4.4.3', gcc-'4.4.3'].
如果您的Prolog没有,那么
成对键\u值
很容易实现。现在,消除重复的键值对:

?- pairs_keys_values(PkgVer, [cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.3']),
|    list_to_set(PkgVer, S).
PkgVer = [cython-'0.11.2', gcc-'4.4.3', gcc-'4.4.3'],
S = [cython-'0.11.2', gcc-'4.4.3'].
这将使用SWI Prolog谓词
列表\u来设置/2
。您还可以使用
排序/2
。解压缩集合:

?- pairs_keys_values(PkgVer, [cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.3']),
|    list_to_set(PkgVer, S),
|    pairs_keys_values(S, Packages, _).
PkgVer = [cython-'0.11.2', gcc-'4.4.3', gcc-'4.4.3'],
S = [cython-'0.11.2', gcc-'4.4.3'],
Packages = [cython, gcc] .
最后,您可以检查
Packages
是否是一个带有SWI的
is\u set
谓词的集合或其一些重新实现(提示:
sort/2
列表,然后检查长度是否更改)。所以


首先,让我们
zip
列表,将它们组合成一个成对的列表:

?- pairs_keys_values(PkgVer, [cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.3']).
PkgVer = [cython-'0.11.2', gcc-'4.4.3', gcc-'4.4.3'].
如果您的Prolog没有,那么
成对键\u值
很容易实现。现在,消除重复的键值对:

?- pairs_keys_values(PkgVer, [cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.3']),
|    list_to_set(PkgVer, S).
PkgVer = [cython-'0.11.2', gcc-'4.4.3', gcc-'4.4.3'],
S = [cython-'0.11.2', gcc-'4.4.3'].
这将使用SWI Prolog谓词
列表\u来设置/2
。您还可以使用
排序/2
。解压缩集合:

?- pairs_keys_values(PkgVer, [cython, gcc, gcc], ['0.11.2', '4.4.3', '4.4.3']),
|    list_to_set(PkgVer, S),
|    pairs_keys_values(S, Packages, _).
PkgVer = [cython-'0.11.2', gcc-'4.4.3', gcc-'4.4.3'],
S = [cython-'0.11.2', gcc-'4.4.3'],
Packages = [cython, gcc] .
最后,您可以检查
Packages
是否是一个带有SWI的
is\u set
谓词的集合或其一些重新实现(提示:
sort/2
列表,然后检查长度是否更改)。所以


下面是一个简单的实现:

conflict_free(Packages, Versions) :-
    \+ (nth1(I, Packages, P),
        nth1(I, Versions, A),
        nth1(J, Packages, P), J \= I,
        nth1(J, Versions, B), A \= B ).
测试:

nth1/3用于将包与位置处的版本配对,因此规则可以如下所示:

没有列出具有不同版本的包


下面是一个简单的实现:

conflict_free(Packages, Versions) :-
    \+ (nth1(I, Packages, P),
        nth1(I, Versions, A),
        nth1(J, Packages, P), J \= I,
        nth1(J, Versions, B), A \= B ).
测试:

nth1/3用于将包与位置处的版本配对,因此规则可以如下所示:

没有列出具有不同版本的包


这个版本比我的短,但运行时间是二次的。是的,测试在I和J交换的情况下重复。简单在这里有一些额外的成本…这不是重点。即使跳过
I
J
,其中
J>=I
,也会循环n*(n-1)/2=O(n²)次。我的版本可以在O(n lg n)甚至O(n)时间内运行,这取决于
列表到设置
是设置
的实现方式。此版本比我的版本短,但以二次时间运行。是的,在交换I和J的情况下重复测试。简单在这里有一些额外的成本…这不是重点。即使跳过
I
J
,其中
J>=I
,也会循环n*(n-1)/2=O(n²)次。我的版本可以在O(n lg n)甚至O(n)时间内运行,这取决于
list\u to\u set
is\u set
的实现方式。zip/3可能是/3…@chac:谢谢,我在错误的位置查找该谓词。zip/3可能是/3…@chac:谢谢,我在错误的位置查找该谓词。