1

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

?- 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,然后尝试使用版本列表中的索引并查看是否有任何不同的版本。但这对我不起作用...

有什么建议么?

4

2 回答 2

1

首先,让我们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'].

pairs_keys_values如果你的 Prolog 没有它,它很容易实现。现在,摆脱重复的键值对:

?- 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 谓词list_to_set/2。您也可以使用sort/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是带有 SWIis_set谓词的集合或其某种重新实现(提示:sort/2列表,然后检查长度是否发生变化)。所以,

conflict_free(Packages, Versions) :-
    pairs_keys_values(PkgVer, Packages, Versions),
    list_to_set(PkgVer, PkgVerSet),
    pairs_keys_values(PkgVerSet, PkgSet, _),
    is_set(PkgSet).
于 2012-08-01T11:37:50.997 回答
0

这里有一个简单的实现:

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

测试:

?- 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.

nth1/3 它用于将包与位置处的版本配对,因此规则可以读取:

没有列出不同版本的软件包

于 2012-08-01T13:52:15.133 回答