无法在 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).