CLP Prolog - 逻辑编程

时间:2015-08-27 19:31:41

标签: prolog clpfd

我们有一个列表列表认为示例?- solve([[40,A,B],[30,B],[60,A,B,C]]),label([A,B,C]).将成功替换B = 30,A = 10和C = 20。 此示例的约束是A + B = 40,A + B + C = 60,并且通常每个变量都在0到100之间。每个列表必须以常量开头,并且它至少包含一个变量。

:- use_module(library(clpfd)).

sum([],0).                              % if the list is empty.
sum([X|XS],Z) :-
   sum(XS,Z1),
   X in 0..100,
   Z #= X+Z1.

solveOne([Const|Var]) :-
   sum(Var,Const). 

solve([]).                            % if the list of list is also empty
solve([First|Others]) :-
   solveOne(First),
   solve(Others).

我对基本案例,事实的想法有点怀疑。因为每个列表必须根据约束列出一个变量,另一方面我们考虑"空列表"情况。?

2 个答案:

答案 0 :(得分:2)

首先,显而易见的问题是:您定义了solve/2solve/1谓词(solve([],0))。 “,0”可能是不受欢迎的。

除此之外,如果你只有一个常数,例如[X],那么solveOne仅在X为零时成功;否则,根据sum([],0)失败。所以,从某种意义上说,如果你认为你的总和总是严格为正,那么你间接检查你至少可以得到一个变量。

为了明确检查是否有效至少有一个变量,您可以按如下方式修改solveOne

 solveOne([Const,V1|Vars]) :-
    sum([V1|Vars], Const).

答案 1 :(得分:1)

@coredump回答应该让你走上正轨。如果您对编写精益代码感兴趣,请考虑这个更简洁的定义(在SWI-Prolog中测试)

solve(L) :- maplist(solveOne, L).
solveOne([C|Vs]) :- Vs ins 0..100, sum(Vs, #=, C).

?- solve([[40,A,B],[30,B],[60,A,B,C]]).
A = 10,
B = 30,
C = 20.