2015-08-27 87 views
2

我們有一個列表清單認爲例?- 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之間。每個列表必須以一個常量開始,它至少包含一個變量。CLP Prolog - 邏輯編程

:- 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

首先,明顯的問題是:您定義了一個solve/2和一個solve/1謂詞(solve([],0))。 「,0」可能是不需要的。

除此之外,如果您只有一個常量,如[X],那麼solveOne只有在X爲零時纔會成功;否則,根據sum([],0)失敗。所以,從某種意義上說,如果你認爲你的總和總是肯定的,你間接檢查你是否至少有一個變量。

爲了明確地檢查,有效地至少有一個變量,那麼你可以修改solveOne如下:

solveOne([Const,V1|Vars]) :- 
    sum([V1|Vars], Const). 
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.