Search code examples
prologclpfd

Define the predicate Prolog


I'm reviewing some exercise for the coming test and having difficulty at this.

Given a list of integers L, define the predicate: add(L,S) which returns a list of integers S in which each element is the sum of all the elements in L up to the same position.

Example:

?- add([1,2,3,4,5],S).

S = [1,3,6,10,15].

So my question is what define the predicate means? It looks pretty general. I've read some threads but they did not provide much. Thanks!


Solution

  • Define the predicate simply means write a predicate that does what the question requires. In your question you have to write the definition of add/2 predicate( "/2" means that it has two arguments). You could write the definition below:

    add(L,S):- add1(L,0,S).
    
    add1([],_,[]).
    add1([H|T],Sum,[H1|T1]):- H1 is Sum+H,NSum is Sum+H,add1(T,NSum,T1).
    

    The above predicate gives you the desired output. A simple example:

    ?- add([1,2,3,4,5],S).
    S = [1, 3, 6, 10, 15].
    

    I think the above or something similar predicate is what someone would wait to see in a test.

    Some additional information-issues

    The problem with the predicate above is that if you query for example:

    ?- add(S,L).
    S = L, L = [] ;
    ERROR: is/2: Arguments are not sufficiently instantiated
    

    As you see when you try to ask when your predicate succeeds it gives an obvious solutions and for further solutions it throws an error. This is not a very good-desired property. You could improve that by using module CLPFD:

    :- use_module(library(clpfd)).
    
    
    add(L,S):- add1(L,0,S).
    
    add1([],_,[]).
    add1([H|T],Sum,[H1|T1]):- H1 #= Sum+H,NSum #= Sum+H,add1(T,NSum,T1).
    

    Now some querying:

    ?- add([1,2,3,4,5],S).
    S = [1, 3, 6, 10, 15].
    
    ?- add(S,[1,3,6]).
    S = [1, 2, 3].
    
    ?- add(S,L).
    S = L, L = [] ;
    S = L, L = [_G1007],
    _G1007 in inf..sup ;
    S = [_G1282, _G1285],
    L = [_G1282, _G1297],
    _G1282+_G1285#=_G1307,
    _G1282+_G1285#=_G1297 ;
    
    ...and goes on..
    

    As you can see now the predicate is in the position to give any information you ask! That's because now it has a more relational behavior instead of the functional behavior that it had before due to is/2 predicate. (These are some more information to improve the predicate's behavior. For the test you might not be allowed to use libraries etc... so you may write just a simple solution that at least answers the question).