在 Prolog 中使用模式匹配查找子多集
Using Pattern Matching in Prolog to Find Submultisets
我是 prolog 的新手,我想知道是否有人可以帮助我解决这个问题。问题:给定整数 1,2,3,4 和谓词 mult/2、div/2、div/2、minus/2 和 minus/2,以及 eval/2,我需要写一个谓词 solutions/1,当这样调用时:
?- solutions(L).
它应该以统一为值为 6 的表达式列表的变量 L 结束。表达式的形式为:
X, Y, exp/2
但是我的代码不起作用。我有两个版本。第一个冻结 SWI-Prolog,在我输入一个句点后不返回任何答案,之后也不让我评估任何其他内容:
eval(1,1.0).
eval(2,2.0).
eval(3,3.0).
eval(4,4.0).
eval(mult(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A*B.
eval(div(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A/B.
eval(minus(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A-B.
solutions(L) :-
setof(X,eval(X,6),L),
print(L).
当我键入 ?- solutions(L).
:
时,第二个版本只是 returns false
solutions(L) :-
setof([exp,X,Y],eval(exp(X,Y),6),L),
print(L).
非常感谢您抽出宝贵时间提供帮助!
问题是您的代码正在使用 eval/2 谓词进行无限递归。
您可以试试这个解决方案:
num(1).
num(2).
num(3).
num(4).
eval(mult(A,B),Z) :-
num(A),
num(B),
Z is A*B.
eval(div(A,B),Z) :-
num(A),
num(B),
Z is A/B.
eval(minus(A,B),Z) :-
num(A),
num(B),
Z is A-B.
test(L) :-
setof(X,eval(X,6),L),
print(L).
产生:
?- test(L).
[mult(2,3),mult(3,2)]
L = [mult(2, 3), mult(3, 2)].
也许您正在寻找类似
的东西
solutions(L) :-
Ns = [1,2,3,4],
Ex = [*,/,-],
findall((X,Y,E),
(member(X,Ns),member(Y,Ns),member(E,Ex),F=..[E,X,Y],6=:=F),
L).
产生
?- solutions(L).
L = [(2, 3, (*)), (3, 2, (*))].
表达式通常是递归的,也就是说,参数可以是表达式而不是纯数字。但是,在我看来,您的问题未明确说明,因为我们 需要 标准来阻止解决方案的无限流动 - 例如 - 通过重复应用不改变值的操作。比如乘以或除以 1。
我是 prolog 的新手,我想知道是否有人可以帮助我解决这个问题。问题:给定整数 1,2,3,4 和谓词 mult/2、div/2、div/2、minus/2 和 minus/2,以及 eval/2,我需要写一个谓词 solutions/1,当这样调用时:
?- solutions(L).
它应该以统一为值为 6 的表达式列表的变量 L 结束。表达式的形式为:
X, Y, exp/2
但是我的代码不起作用。我有两个版本。第一个冻结 SWI-Prolog,在我输入一个句点后不返回任何答案,之后也不让我评估任何其他内容:
eval(1,1.0).
eval(2,2.0).
eval(3,3.0).
eval(4,4.0).
eval(mult(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A*B.
eval(div(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A/B.
eval(minus(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A-B.
solutions(L) :-
setof(X,eval(X,6),L),
print(L).
当我键入 ?- solutions(L).
:
solutions(L) :-
setof([exp,X,Y],eval(exp(X,Y),6),L),
print(L).
非常感谢您抽出宝贵时间提供帮助!
问题是您的代码正在使用 eval/2 谓词进行无限递归。
您可以试试这个解决方案:
num(1).
num(2).
num(3).
num(4).
eval(mult(A,B),Z) :-
num(A),
num(B),
Z is A*B.
eval(div(A,B),Z) :-
num(A),
num(B),
Z is A/B.
eval(minus(A,B),Z) :-
num(A),
num(B),
Z is A-B.
test(L) :-
setof(X,eval(X,6),L),
print(L).
产生:
?- test(L).
[mult(2,3),mult(3,2)]
L = [mult(2, 3), mult(3, 2)].
也许您正在寻找类似
的东西solutions(L) :-
Ns = [1,2,3,4],
Ex = [*,/,-],
findall((X,Y,E),
(member(X,Ns),member(Y,Ns),member(E,Ex),F=..[E,X,Y],6=:=F),
L).
产生
?- solutions(L).
L = [(2, 3, (*)), (3, 2, (*))].
表达式通常是递归的,也就是说,参数可以是表达式而不是纯数字。但是,在我看来,您的问题未明确说明,因为我们 需要 标准来阻止解决方案的无限流动 - 例如 - 通过重复应用不改变值的操作。比如乘以或除以 1。