无法在 Prolog 中检查与未知数的相等性
Can't check equality with unknowns in Prolog
当尝试使用一个简单的程序来查找相乘为 100 的数字时,我可以检查设置值,例如 prod_hundred(2, 50)
,但是如果我想查找具有 prod_hundred(4, X)
的值,我得到:
Arguments are not sufficiently instantiated
In:
[1] 4*_1680=:=100
我知道这是因为我不能使用'=:='来评估未知数,但是使用==它只是将"2*50"
与"100"
进行比较,而不是评估[=16] =]
代码:
prod_hundred(X, Y) :- X*Y =:= 100.
?- prod_hundred(4, X).
Arguments are not sufficiently instantiated
In:
[1] 2*_1680=:=100
“求解 X”比计算 2*50
更难得到结果;它需要有关如何将等式重新排列为 100/4 = X
的数学知识。 Classic Prolog 没有内置,您必须自己编写代码。
但是这种东西存在于较新的约束求解器库中,例如 SWI Prolog 中的 clpfd
,它为您提供 #=
并且可以通过找到数字问题的整数答案来解决:
:- use_module(library(clpfd)).
prod_hundred(X, Y) :-
X*Y #= 100.
然后:
?- prod_hundred(4, X).
X = 25
makes_mult(Tot, X, Y) :-
between(1, Tot, X),
divmod(Tot, X, Y, 0).
swi-prolog 中的结果:
?- time(findall((X, Y), makes_mult(100, X, Y), Tuples)).
% 220 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 575084 Lips)
Tuples = [(1,100),(2,50),(4,25),(5,20),(10,10),(20,5),(25,4),(50,2),(100,1)].
尝试
factor(F,N) :- integer(N),
L is N // 2 ,
( between(1,L,F) ; N ),
0 =:= N rem F
.
factors(X,Y,Z) :- integer(Z),
factor(X,Z),
factor(Y,Z),
Z is X * Y
.
prod_hundred(X,Y) :- factors(X,Y,100).
当尝试使用一个简单的程序来查找相乘为 100 的数字时,我可以检查设置值,例如 prod_hundred(2, 50)
,但是如果我想查找具有 prod_hundred(4, X)
的值,我得到:
Arguments are not sufficiently instantiated
In:
[1] 4*_1680=:=100
我知道这是因为我不能使用'=:='来评估未知数,但是使用==它只是将"2*50"
与"100"
进行比较,而不是评估[=16] =]
代码:
prod_hundred(X, Y) :- X*Y =:= 100.
?- prod_hundred(4, X).
Arguments are not sufficiently instantiated
In:
[1] 2*_1680=:=100
“求解 X”比计算 2*50
更难得到结果;它需要有关如何将等式重新排列为 100/4 = X
的数学知识。 Classic Prolog 没有内置,您必须自己编写代码。
但是这种东西存在于较新的约束求解器库中,例如 SWI Prolog 中的 clpfd
,它为您提供 #=
并且可以通过找到数字问题的整数答案来解决:
:- use_module(library(clpfd)).
prod_hundred(X, Y) :-
X*Y #= 100.
然后:
?- prod_hundred(4, X).
X = 25
makes_mult(Tot, X, Y) :-
between(1, Tot, X),
divmod(Tot, X, Y, 0).
swi-prolog 中的结果:
?- time(findall((X, Y), makes_mult(100, X, Y), Tuples)).
% 220 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 575084 Lips)
Tuples = [(1,100),(2,50),(4,25),(5,20),(10,10),(20,5),(25,4),(50,2),(100,1)].
尝试
factor(F,N) :- integer(N),
L is N // 2 ,
( between(1,L,F) ; N ),
0 =:= N rem F
.
factors(X,Y,Z) :- integer(Z),
factor(X,Z),
factor(Y,Z),
Z is X * Y
.
prod_hundred(X,Y) :- factors(X,Y,100).