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:谢谢,我在错误的位置查找该谓词。