limonik
limonik

Reputation: 499

CLP Prolog - Logic Programming

we have a list of list think an example ?- solve([[40,A,B],[30,B],[60,A,B,C]]),label([A,B,C]). will succeed with replacing B=30,A=10 and C=20. The constraint with this example is A+B=40, A+B+C=60 and generally every variable are in between 0 and 100. Every list must begin with a constant and it includes at least one variable.

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

I am a bit skeptic the idea of base case,facts. Because every list must include at list one variable according to constraints, on the other hand we think about the "empty list" situation.?

Upvotes: 2

Views: 255

Answers (2)

CapelliC
CapelliC

Reputation: 60004

@coredump answer should put you on right track. If you are interested in writing lean code, consider this more succint definition (tested in 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.

Upvotes: 1

coredump
coredump

Reputation: 38789

First, the obvious problem: you define both a solve/2 and a solve/1 predicate (solve([],0)). The ",0" is probably unwanted.

Apart from that, if you have only a constant, like [X], then solveOne succeeds only if X is zero; otherwise, it fails according to sum([],0). So, in a sense, you indirectly check that you can have at least one variable if you assume your sum is always strictly positive.

In order to explicitely check that there is effectively at least one variable, then you can modify solveOne as follows:

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

Upvotes: 2

Related Questions