The first exercises are simple 'type and see'-exercises. You can try them yourself.
The non-CLP program for the mortgage-problem looks as follows:
mg(P,0,_,_,P). mg(P,T,I,MP,B) :- T>0, T1 is T-1, mg(P,T1,I,MP,B1), B is B1*(1+I)-MP.
The CLP program looks as follows:
:- use_module(library(clpr)). mg_clp(P,T,_,_,B) :- { T = 0, B = P }. mg_clp(P,T,I,MP,B) :- { T>0, T1 = T - 1, B = B1*(1+I)-MP }, mg_clp(P,T1,I,MP,B1).Here are some queries:
?- mg_clp(100,4,0.1,20,B). B = 53.590000000000046 ? yes ?- mg(100,4,0.1,20,B). B = 53.590000000000046 ? yesAs expected, there is no difference between both predicates when used with all arguments except B instantiated. Now what happens if we try to compute MP given all other arguments?
?- mg_clp(100,4,0.1,MP,0). MP = 31.547080370609795 ? yes ?- mg(100,4,0.1,MP,0). ! Instantiation error in argument 2 of is/2The CLP-predicate works fine. With the pure prolog predicate, however, we get an error. This is because of the line B is B1*(1+I)-MP: 'is' only works if all variables occuring in the right hand side are already instantiated and here MP is not instantiated yet. As a consequence, CLP-predicates are often more flexible (with respect to which arguments should be instantiated and which not) than pure prolog predicates.
:- use_module(library(clpfd)). exactly(_El, [], 0). exactly(El, [H|List], N) :- El #= H #<=> B, N #= M+B, exactly(El, List, M).
safe(L) :- L = [A,B,C,D,E,F,G,H,I], % A=1st digit, B=2nd digit, ... domain(L, 1, 9), all_distinct(L), self_distinct(L, 1), (D-F #= G) #\/ (F-D #= G), % difference between D and F can be D-F or F-D A*B*C #= H+I, B+C+F #< H, I #< H, labeling([],L). self_distinct([],_). self_distinct([H|T],N) :- H #\= N, M is N+1, self_distinct(T,M).Here is the solution:
?- safe(L). L = [4,3,1,8,9,2,6,7,5] ?
config(L) :- L= [G,M,O,P,R,Y], % G=number of cup with Green ball, ... domain(L,1,6), all_different(L), M #= 1, G #= 5, P #< O, R #= M + 1 #<=> B1, R #= M - 1 #<=> B2, B1 + B2 #= 1, labeling([], L).Here is the solution:
?- config(L). L = [5,1,4,3,2,6] ? ; L = [5,1,6,3,2,4] ? ; L = [5,1,6,4,2,3] ? ; no