如何找到应用限制的两个数字

时间:2017-01-22 13:30:32

标签: prolog

让我们说我想要找到两个数字,其中这些数字的总和是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 ;
  ... 

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.

确实无需使用列表来管理变量AB,但如果您愿意,可以使用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 实例化 AB到列表提供的值,所以1..9,接下来使用is/2 1}}计算总和并验证总和等于N。如果N is A+BA获得了适当的值,则只能致电B。最后我们说A \= BA不等于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.

但是,您也可以使用已填写的AB进行查询,或填写其中一个,或者保留金额。所以:

?- 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.