% declaration to load rational solver
:- use_module(library(r)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 4.1 User Defined Constraints %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% parallel_resistors rule p134.
parallel_resistors(V,I,R1,R2) :- V $= I1*R1, V $= I2*R2, I1+I2 $= I.
%% first goal on p134.
gp134a(V,I,R1,R2) :-
parallel_resistors(V,I,R1,R2), R1 $= 10, R2 $= 5.
%% second goal on p134.
gp134b(I,R) :-
parallel_resistors(10,I,R,R).
%% goal for example 4.2 p135.
gp135(V,I) :-
parallel_resistors(VA, IA, 10, 5),
parallel_resistors(VB, IB, 8, 3),
VA + VB $= V, I $= IB, I $= IA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 4.2 Programming with Rules %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Rules for voltage divider program p138.
voltage_divider(V, I, R1, R2, VD, ID) :-
V1 $= I * R1, VD $= I2 * R2, V $= V1 + VD, I $= I2 + ID.
cell(V) :- V $= 9. % note that the constraints must be explicit
cell(V) :- V $= 12.
resistor(R) :- R $= 5.
resistor(R) :- R $= 9.
resistor(R) :- R $= 14.
%% Goal for voltage divider program p138.
gp138(V,R1,R2) :-
voltage_divider(V, _I, R1, R2, VD, ID),
5.4 $<= VD, VD $<= 5.5, ID $= 0.1,
cell(V), resistor(R1), resistor(R2).
% Factorial program p139.
fac(N,F) :- N $= 0, F $= 1.
fac(N, NF) :- N $>= 1, NF $= N * F, N1 $= N - 1, fac(N1,F).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 4.3 Evaluation %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Goals for factorial program
gp140(X) :- fac(2,X).
gp143(X) :- X = 2, nodefinition(X).
gp146 :- fac(0,2).
gp155(F) :- F $<= 0, fac(0,F).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 4.4 Derivation Trees and Finite Failure %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Stupid program for infinite derivations p 146
stupid(X) :- stupid(X).
stupid(X) :- X $= 1.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 4.7 The CLP Scheme %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% delete program p152.
delete_(cons(Y,X), Y, X).
delete_(cons(A,X), Y, cons(A,Z)) :- delete_(X, Y, Z).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 4.8 Independence from Rule Ordering and Literal Selection %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% infinite program
p :- p.
% goal showing order dependence for finite failure
gp157a :- p, 1 $= 2.
gp157b :- 1 $= 2, p.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 4.10 Exercises %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exercise 4.1
p41(A,B) :- A $= 0, B $= 0.
p41(X,B) :- B $= (X*X)+Y, X1 $= X - 1, p41(X1,Y).
gex41(Y) :- p41(2,Y).
% Exercise 4.2
p42(X, B) :- X $>= 1, B $= Y + X, X1 $= X - 1, p42(X1, Y).
p42(A, B) :- A $= 0, B $= 0.
q42(X, B) :- X $>= 1, Y $>= 0, B $= Y + X, X1 $= X - 1, q42(X1, Y).
q42(A, B) :- A $= 0, B $= 0.
gex42a(X) :- p42(X,3).
gex42b(X) :- q42(X,3).
% Exercise 4.3
p43(X,Y) :- X $= Y + 2, Y $>= 0, q43(X,Y).
q43(X,Y) :- X $<= 1, r43(X, Y).
q43(X,Y) :- X $<= 3, r43(X, Y).
r43(A,B) :- A $= 2, B $= 0.
r43(_X,B) :- B $= 2.
% Exercise 4.4
gex44a(X,R) :- delete_(cons(a, cons(b, nil)), X, R).
gex44b(L) :- delete_(cons(a, cons(b, nil)), b, L).