Prolog - 笛卡尔积计算器
Prolog - Cartesian product calculator
我需要为 Prolog 创建笛卡尔积计算器。它应该像这样工作:
输入:product([1,2,3], [a,b], X).
输出:X = [[1,a],[2,a],[3,a],[1,b],[2,b],[3,b]].
我知道网上有例子,但我想自己写点东西。
这是我的代码,我认为它非常接近,但由于某些原因它并不完全有效。伙计们,有什么想法吗?
% call new with 4 parameters (so we can keep List1 in memory)
product(L1,L2,L3):- product(L1,L2,L3,L1).
% stop when both List1 and List2 are empty
product([], [], [], []).
% first list is empty, recreate it and work it again with the next element of second list (and shorten memory)
product([], [_|T2], List3, [H4|T4]):-
product([H4|T4], T2, List3, T4).
%go through first list and always first element of second list to our answer
product([H1|T1], [H2|T2], [[H1,H2]|T3], List4):-
product(T1, [H2|T2], T3, List4).
您应该更改子句:
product([], [], [], []).
至:
product(_, [], [], _).
那是因为当 L2 变空时,它会调用 product(L1,[],L3,L4),其中 L1 和 L4 不为空。您的基本情况必须是 L2 变空(然后 L3 变空作为输出列表)并且其他列表可能包含元素:
?- product([1,2,3], [a,b], X).
X = [[1, a], [2, a], [3, a], [1, b], [2, b], [3, b]] ;
false.
正如 Coder (+1) 所说,您应该将终止子句从
product([], [], [], []).
到
product(_, [], [], _).
但这还不够。
您应该将第三个子句从
product([], [_|T2], List3, [H4|T4]):-
product([H4|T4], T2, List3, T4).
到
product([], [_|T2], List3, L4):-
product(L4, T2, List3, L4).
我的意思是:使用保存的列表1是一个错误。
使用您的版本,来自
product([1,2,3,4,5], [a,b,c,d], X),
你只得到
[[1,a],[2,a],[3,a],[4,a],[5,a],[1,b],[2,b],[3,b],[4,b],[5,b],[2,c],[3,c],[4,c],[5,c],[3,d],[4,d],[5,d]]
也就是说:你失去了 [1,c]
、[1,d]
和 [2,d]
。
在SWI-Prolog中,也可以使用findall/3 and member/2谓词生成笛卡尔积:
:- initialization(main).
:- set_prolog_flag(double_quotes, chars).
main :-
product([1,2,3], [a,b], X),
writeln(X).
product(A,B,C) :-
findall([X,Y],(member(X,A),member(Y,B)),C).
这个程序打印 [[1,a],[1,b],[2,a],[2,b],[3,a],[3,b]]
.
我需要为 Prolog 创建笛卡尔积计算器。它应该像这样工作:
输入:product([1,2,3], [a,b], X).
输出:X = [[1,a],[2,a],[3,a],[1,b],[2,b],[3,b]].
我知道网上有例子,但我想自己写点东西。
这是我的代码,我认为它非常接近,但由于某些原因它并不完全有效。伙计们,有什么想法吗?
% call new with 4 parameters (so we can keep List1 in memory)
product(L1,L2,L3):- product(L1,L2,L3,L1).
% stop when both List1 and List2 are empty
product([], [], [], []).
% first list is empty, recreate it and work it again with the next element of second list (and shorten memory)
product([], [_|T2], List3, [H4|T4]):-
product([H4|T4], T2, List3, T4).
%go through first list and always first element of second list to our answer
product([H1|T1], [H2|T2], [[H1,H2]|T3], List4):-
product(T1, [H2|T2], T3, List4).
您应该更改子句:
product([], [], [], []).
至:
product(_, [], [], _).
那是因为当 L2 变空时,它会调用 product(L1,[],L3,L4),其中 L1 和 L4 不为空。您的基本情况必须是 L2 变空(然后 L3 变空作为输出列表)并且其他列表可能包含元素:
?- product([1,2,3], [a,b], X).
X = [[1, a], [2, a], [3, a], [1, b], [2, b], [3, b]] ;
false.
正如 Coder (+1) 所说,您应该将终止子句从
product([], [], [], []).
到
product(_, [], [], _).
但这还不够。
您应该将第三个子句从
product([], [_|T2], List3, [H4|T4]):-
product([H4|T4], T2, List3, T4).
到
product([], [_|T2], List3, L4):-
product(L4, T2, List3, L4).
我的意思是:使用保存的列表1是一个错误。
使用您的版本,来自
product([1,2,3,4,5], [a,b,c,d], X),
你只得到
[[1,a],[2,a],[3,a],[4,a],[5,a],[1,b],[2,b],[3,b],[4,b],[5,b],[2,c],[3,c],[4,c],[5,c],[3,d],[4,d],[5,d]]
也就是说:你失去了 [1,c]
、[1,d]
和 [2,d]
。
在SWI-Prolog中,也可以使用findall/3 and member/2谓词生成笛卡尔积:
:- initialization(main).
:- set_prolog_flag(double_quotes, chars).
main :-
product([1,2,3], [a,b], X),
writeln(X).
product(A,B,C) :-
findall([X,Y],(member(X,A),member(Y,B)),C).
这个程序打印 [[1,a],[1,b],[2,a],[2,b],[3,a],[3,b]]
.