让我们说我想要找到两个数字,其中这些数字的总和是8,是1-9,必须是不同的(显然这些数字是(7,1),(6,2)等等因为我写了。
dif_list([H|T]):- \+ member(H,T),dif_list(T).
dif_list([]).
check1_9([H|T]):-H>=1,H=<9,check1_9(T).
check1_9([]).
find_number([A,B],N) :- N =:= A+B,dif_list([A,B]),check1_9([A,B]).
之后我会问prolog
?-find_number([A,B],8).
ERROR: =:=/2: Arguments are not sufficiently instantiated
我的目标是prolog将为我打印结果。例如:
?-find_number([A,B],8).
A = 7,
B = 1 ;
A = 6,
B = 2 ;
...
答案 0 :(得分:2)
在Prolog中处理此类问题的最佳方法是使用CLP(FD)库:
:- [library(clpfd)].
sum_of(A, B, Sum) :-
A #> 0,
B #> 0,
A + B #= Sum.
?- sum_of(A, B, 8), label([A, B]).
A = 1,
B = 7 ;
A = 2,
B = 6 ;
A = 3,
B = 5 ;
A = B, B = 4 ;
A = 5,
B = 3 ;
A = 6,
B = 2 ;
A = 7,
B = 1.
?-
如果您希望加数是唯一的,则可以进一步限制它:
sum_of(A, B, Sum) :-
A #> 0,
B #>= A,
A + B #= Sum.
确实无需使用列表来管理变量A
和B
,但如果您愿意,可以使用sum_of([A,B], Sum)
。
答案 1 :(得分:-1)
Prolog不是声明性的:确实存在答案集编程(ASP)或约束逻辑编程(clp)语言,您可以在其中简单地定义一组约束和有限域求解器旨在解决它(但这将需要相当长的时间)。
我建议您按如下方式定义程序:
find_number(A,B,N) :-
member(A,[1,2,3,4,5,6,7,8,9]),
member(B,[1,2,3,4,5,6,7,8,9]),
N is A+B,
A \= B.
此处member/2
实例化 A
和B
到列表提供的值,所以1..9
,接下来使用is/2
1}}计算总和并验证总和等于N
。如果N is A+B
和A
获得了适当的值,则只能致电B
。最后我们说A \= B
(A
不等于B
)。
运行此谓词时,它会生成:
?- find_number(A,B,8).
A = 1,
B = 7 ;
A = 2,
B = 6 ;
A = 3,
B = 5 ;
A = 5,
B = 3 ;
A = 6,
B = 2 ;
A = 7,
B = 1 ;
false.
但是,您也可以使用已填写的A
和B
进行查询,或填写其中一个,或者保留金额。所以:
?- find_number(A,2,8).
A = 6 ;
false.
或:
?- find_number(A,2,N).
A = 1,
N = 3 ;
A = 3,
N = 5 ;
A = 4,
N = 6 ;
A = 5,
N = 7 ;
A = 6,
N = 8 ;
A = 7,
N = 9 ;
A = 8,
N = 10 ;
A = 9,
N = 11 ;
false.