Checking descendants of a family tree in Prolog - recursion

How can I recursively check if X is the descendent of Y, using a recursive method descendent_of? The fact base consists of males and females, and father_of/mother_of statements.
/* Facts */
male(roy).
male(lee).
...
female(joy).
female(ana).
...
/* Rules */
grandmother_of(X, Z) :-
mother_of(X, Y),
(mother_of(Y, Z);
father_of(Y, Z)).
grandfather_of(X, Z) :-
father_of(X, Y),
(mother_of(Y, Z);
father_of(Y, Z)).
parent_of(X,Y) :-
mother_of(X,Y);father_of(X,Y).
descendent_of(X,Y) :-
*/ Recursive method here */
How do I set up the stopping condition? Also, how does recursion work in prolog if functions only return boolean values?
Any comments/suggestions are greatly appreciated.

If you look at descendant_of(X,Y) it should be true if X is descendant of Y. The truth value is than reursivly defined as follows:
I do here a little trick to achieve consistency with parent_of and introduce the predicate ancestor_of/2 as
descendent_of(X,Y) :- ancestor_of(Y,X)
Know X is ancestor of Y if either
X is parent of Y or
X is parent of Z and Z is descendant of Y
(1) is the base case of the recursion and (2) is the recursive definition.
Hint: You could also redefine the recursive case as: Z is descendant of Y and X is parent of Z (Keyword tail-recursion)

I've extended your facts to give some working data.
/* Facts */
male(roy).
male(lee).
female(joy).
female(ana).
parent_of(roy,joy).
parent_of(joy,ana).
parent_of(lee,ana).
Now we can build some rules. Let's start with grand_parent_of/2.
grand_parent_of(X,Z) :-
parent_of(X,Y),
parent_of(Y,Z).
This keeps the rules for grand_father_of/2 and grand_mother_of/2 rather simple.
grand_father_of(X,Y) :-
male(X),
grand_parent_of(X,Y).
grand_mother_of(X,Y) :-
female(X),
grand_parent_of(X,Y).
Now, every predicate so far the ancestor has been on the left and the descendent on the right, so to keep consistency, let's define ancestor_of/2 first, rather than descendent_of/2.
ancestor_of(X,Y) :-
parent_of(X,Y).
ancestor_of(X,Y) :-
parent_of(X,Z),
ancestor_of(Z,Y).
Note that the second predicate is recursive.
Now we can easily define descendent_of/2 simply in terms of ancestor_of/2.
descendent_of(X,Y) :-
ancestor_of(Y,X).
Here are the results of running the following query and asking prolog to keep giving me results.
?- descendent_of(X,Y).
X = joy,
Y = roy ;
X = ana,
Y = joy ;
X = ana,
Y = lee ;
X = ana,
Y = roy ;
false.

Related

Prolog - Printing Result After Two Recursive Rules | Sum of Squares

I am brand new to prolog and I feel like there is a concept that I am failing to understand, which is preventing me from grasping the concept of recursion in prolog. I am trying to return S, which is the sum of the square of each digit, taken as a list from an integer that is entered by the user in a query. E.g The user enters 12345, I must return S = (1^2)+(2^2)+(3^2)+(4^2)+(5^2) = 55.
In my program below, I understand why the each segment of the calculation of S is printed multiple time as it is part of the recursive rule. However, I do not understand how I would be able to print S as the final result. I figured that I could set a variable = to the result from sos in the second rule and add it as a parameter for intToList but can't seem to figure this one out. The compiler warns that S is a singleton variable in the intToList rule.
sos([],0).
sos([H|T],S) :-
sos(T, S1),
S is (S1 + (H * H)),
write('S is: '),write(S),nl.
intToList(0,[]).
intToList(N,[H|T]) :-
N1 is floor(N/10),
H is N mod 10,
intToList(N1,T),
sos([H|T],S).
The issue with your original code is that you're trying to handle your call to sos/2 within your recursive clause for intToList/2. Break it out (and rename intToList/2 to something more meaningful):
sosDigits(Number, SoS) :-
number_digits(Number, Digits),
sos(Digits, SoS).
Here's your original sos/2 without the write, which seems to work fine:
sos([], 0).
sos([H|T], S) :-
sos(T, S1),
S is (S1 + (H * H)).
Or better, use an accumulator for tail recursion:
sos(Numbers, SoS) :-
sos(Numbers, 0, SoS).
sos([], SoS, SoS).
sos([X|Xs], A, SoS) :-
A1 is A + X*X,
sos(Xs, A1, SoS).
You can also implement sos/2 using maplist/3 and sumlist/2:
square(X, S) :- S is X * X.
sos(Numbers, SoS) :- maplist(square, Numbers, Squares), sumlist(Squares, SoS).
Your intToList/2 needs to be refactored using an accumulator to maintain correct digit order and to get rid of the call to sos/2. Renamed as explained above:
number_digits(Number, Digits) :-
number_digits(Number, [], Digits).
number_digits(Number, DigitsSoFar, [Number | DigitsSoFar]) :-
Number < 10.
number_digits(Number, DigitsSoFar, Digits) :-
Number >= 10,
NumberPrefix is Number div 10,
ThisDigit is Number mod 10,
number_digits(NumberPrefix, [ThisDigit | DigitsSoFar], Digits).
The above number_digits/2 also handles 0 correctly, so that number_digits(0, Digits) yields Digit = [0] rather than Digits = [].
You can rewrite the above implementation of number_digits/3 using the -> ; construct:
number_digits(Number, DigitsSoFar, Digits) :-
( Number < 10
-> Digits = [Number | DigitsSoFar]
; NumberPrefix is Number div 10,
ThisDigit is Number mod 10,
number_digits(NumberPrefix, [ThisDigit | DigitsSoFar], Digits)
).
Then it won't leave a choice point.
Try this:
sos([],Accumulator,Accumulator).
sos([H|T],Accumulator,Result_out) :-
Square is H * H,
Accumulator1 is Accumulator + Square,
sos(T,Accumulator1,Result_out).
int_to_list(N,R) :-
atom_chars(N,Digit_Chars),
int_to_list1(Digit_Chars,Digits),
sos(Digits,0,R).
int_to_list1([],[]).
int_to_list1([Digit_Char|Digit_Chars],[Digit|Digits]) :-
atom_number(Digit_Char,Digit),
int_to_list1(Digit_Chars,Digits).
For int_to_list I used atom_chars which is built-in e.g.
?- atom_chars(12345,R).
R = ['1', '2', '3', '4', '5'].
And then used a typical loop to convert each character to a number using atom_number e.g.
?- atom_number('2',R).
R = 2.
For sos I used an accumulator to accumulate the answer, and then once the list was empty moved the value in the accumulator to the result with
sos([],Accumulator,Accumulator).
Notice that there are to different variables for the accumulator e.g.
Accumulator1 is Accumulator + Square,
sos(T,Accumulator1,Result_out).
this is because in Prolog variables are immutable, so one can not keep assigning new values to the same variable.
Here are some example runs
?- int_to_list(1234,R).
R = 30.
?- int_to_list(12345,R).
R = 55.
?- int_to_list(123456,R).
R = 91.
If you have any questions just ask in the comments under this answer.

Lenses in Prolog via DCG, possible or not?

Was playing around with lenses in Prolog. Lenses are a kind of microscope that allow to zoom into a structure and do some reads or writes in a functional fashion. Basically my point of departure was the following modelling of setters and declarative getters in Prolog:
Getter: Just a <closure>,
called as call(<closure>, X, Y),
this will retrieve the value Y from X.
Declarative Setter: The same <closure> but used with a different arity,
called as call(<closure>, X, Y, Z), this will update the X by a new value Y giving a new Z.
I quickly arrived at a definition of a lens composition operator #, which can be used to combine two lenses into a new one, just based on their closures. An example and a definition is found in the appendix. But according to this article lenses can be made to be simply compositional.
In my opinion, when something is compositional it can be easily modelled via DCG. I can do this for the getter as follows, but I did not yet figure out a way to do it for the declarative setter as well:
/* Getter composition as DCG */
#(C1, C2) -->
call(C1),
call(C2).
How would I model the setter composition in DCG? Is this possible, maybe altering the intial assumptions of how the getters and declarative setters are modelled, so that the result is simply compositional?
Best Regards
Appendix:
Here is an example of some setters and getters:
/* getter */
back(bicycle(X, _), X).
front(bicycle(_, Y), Y).
circumference(wheel(X, _), X).
spokes(wheel(_, Y), Y).
/* setter */
back(bicycle(_, Y), X, bicycle(X, Y)).
front(bicycle(X, _), Y, bicycle(X, Y)).
circumference(wheel(_, Y), X, wheel(X, Y)).
spokes(wheel(X, _), Y, wheel(X, Y)).
Here is the modelling of the lens composition:
:- op(600, xfy, #).
/* getter composition */
#(C1, C2, X, Y) :-
call(C1, X, H),
call(C2, H, Y).
/* setter composition */
#(C1, C2, X, Y, Z) :-
call(C1, X, H),
call(C2, H, Y, J),
call(C1, X, J, Z).
Here is are some example runs:
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.16)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
?- call(front#spokes, bicycle(wheel(1330, 12), wheel(1440, 16)), X).
X = 16.
6 ?- call(back#circumference, bicycle(wheel(1330, 12), wheel(1440, 16)), X).
X = 1330.
7 ?- call(front#circumference, bicycle(wheel(1330, 12), wheel(1440, 16)), 1420, X).
X = bicycle(wheel(1330, 12), wheel(1420, 16)).
There is a solution which has a further indirection, but which has also the potential to somehow precompile access paths. We view access paths again as closures, but this time they modify continuation functions. There are two types of continuation:
Getter Continuation:
- Transforms the value before returning it.
Declarative Setter Continuation:
- Transforms the value by an additional parameter before updating it.
An access path element now transforms the two continuations, to give a new continuation. The access path element transformation is compositional, whereby the inner access elements are first applied.
Some example continuations are given in the appendix, we can then model composition of access elements via DCG as follows. Note the order in the body of the DCG, this reflects aforementioned access elements order.
/* composition */
#(C1, C2) :-
call(C2),
call(C1).
Bye
Appendix:
Here are some transformer definitions:
/* transformer construction */
back(F, back(F)).
front(F, front(F)).
circumference(F, circumference(F)).
spokes(F, spokes(F)).
/* getter transformer */
back(F, bicycle(X, _), Y) :- call(F,X,Y).
front(F, bicycle(_, X), Y) :- call(F,X,Y).
circumference(F, wheel(X, _), Y) :- call(F,X,Y).
spokes(F, wheel(_, X), Y) :- call(F,X,Y).
/* setter transformer */
back(F, bicycle(X, Y), Z, bicycle(T, Y)) :- call(F,X,Z,T).
front(F, bicycle(X, Y), Z, bicycle(X, T)) :- call(F,Y,Z,T).
circumference(F, wheel(X, Y), Z, wheel(T, Y)) :- call(F,X,Z,T).
spokes(F, wheel(X, Y), Z, wheel(X, T)) :- call(F,Y,Z,T).
Here is the lens composition and some stop transformer:
:- op(600, xfy, #).
/* composition */
#(C1, C2, F, G) :-
call(C2, F, H),
call(C1, H, G).
/* stop getter */
id(X,X).
/* stop setter */
id(_,X,X).
here are some example runs:
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.14-1-ga20f192)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
?- ['lens.pro'].
?- call(front#spokes, id, F), call(F, bicycle(wheel(1330, 12), wheel(1440, 16)), X).
F = front(spokes(id)),
X = 16.
?- call(back#circumference, id, F), call(F, bicycle(wheel(1330, 12), wheel(1440, 16)), X).
F = back(circumference(id)),
X = 1330.
?- call(front#circumference, id, F), call(F, bicycle(wheel(1330, 12), wheel(1440, 16)), 1420, X).
F = front(circumference(id)),
X = bicycle(wheel(1330, 12), wheel(1420, 16)).

Recursion in prolog using append

I'm new in Prolog and I have some problem understanding how the recursion works.
The think I want to do is to create a list of numbers (to later draw a graphic).
So I have this code :
nbClassTest(0, _).
nbClassTest(X, L) :-
numberTestClass(A,X),
append([A], L, L),
X is X - 1,
nbClassTest(X, L).
But it keeps giving me 'false' as an answer and I don't understand why it doesn't fill the list. It should end if X reaches 0 right?
The numberTestClass(A,X), gives me a number (in the variable A) for some X as if it was a function.
You should build the list without appending, because it's rather inefficient.
This code could do:
nbClassTest(0, []).
nbClassTest(X, [A|R]) :-
numberTestClass(A, X),
X is X - 1,
nbClassTest(X, R).
or, if your system has between/3, you can use an 'all solutions' idiom:
nbClassTest(X, L) :-
findall(A, (between(1, X, N), numberTestClass(A, X)), R),
reverse(R, L).
the problem is that you use the same variable for the old and the new list. right now your first to append/3 creates a list of infinite length consisting of elements equal to the value of A.
?-append([42],L,L).
L = [42|L].
?- append([42],L,L), [A,B,C,D|E]=L.
L = [42|L],
A = B, B = C, C = D, D = 42,
E = [42|L].
then, if the next A is not the same with the previous A it will fail.
?- append([42],L,L), append([41],L,L).
false.
there is still on more issue with the code; your base case has an non-instantiated variable. you might want that but i believe that you actually want an empty list:
nbClassTest(0, []).
nbClassTest(X, L) :-
numberTestClass(A,X),
append([A], L, NL),
X is X - 1,
nbClassTest(X, NL).
last, append/3 is kinda inefficient so you might want to avoid it and build the list the other way around (or use difference lists)
It fails because you use append in wrong way
try
nbClassTest(0, _).
nbClassTest(X, L) :-
numberTestClass(A,X),
append([A], L, Nl),
X is X - 1,
nbClassTest(X, Nl).
append concatenate 2 lists so there is no such list which after adding to it element still will be same list.

Division in prolog

I'm trying to define the division in prolog using the remainder theorem and the well-ordering principle.
I've got thus far:
less(0, s(0)).
less(0, s(B)) :- less(0, B).
less(s(A), s(s(B))) :- less(A, s(B)).
add(A,0,A) :- nat(A).
add(A,s(B),s(C)) :- add(A,B,C). % add(A,B+1,C+1) = add(A,B,C)
add2(A,0,A).
add2(A,s(B),s(C)) :- add2(A,B,C). % add(A,B+1,C+1) = add(A,B,C)
times(A,0,0).
times(A,s(B),X) :- times(A,B,X1),
add(A,X1,X).
eq(0,0).
eq(s(A), s(B)) :- eq(A, B).
% A / B = Q (R) => A = B * Q + R
div(A, B, Q, R) :- less(R, B), eq(A, add(times(Q, R), R)).
But the definition of div is somehow wrong. Could someone please give me a hint?
PS: I shouldn't be using eq, but I couldn't get is or = to work.
In SWI-Prolog, you can try ?- gtrace, your_goal. to use the graphical tracer and see what goes wrong. Instead of eq(A, add(times(Q, R), R)), you should write for example: times(Q, R, T), add(T, R, A), since you want to use the "times/3" and "add/3" predicates, instead of just calling the "eq/2" predicate with a compound term consisting of "add/2" and "times/2" as its second argument. There are other problems with the code as well, for example, the definition of nat/1 is missing, but I hope this helps somewhat.

map function if a predicate holds

I feel like this should be fairly obvious, or easy, but I just can't get it. What I want to do is apply a function to a list (using map) but only if a condition is held. Imagine you only wanted to divide the numbers which were even:
map (`div` 2) (even) [1,2,3,4]
And that would give out [1,1,3,2] since only the even numbers would have the function applied to them. Obviously this doesn't work, but is there a way to make this work without having to write a separate function that you can give to map? filter is almost there, except I also want to keep the elements which the condition doesn't hold for, and just not apply the function to them.
If you don't want to define separate function, then use lambda.
map (\x -> if (even x) then (x `div` 2) else x) [1,2,3,4]
Or instead of a map, list comprehension, bit more readable I think.
[if (even x) then (x `div` 2) else x | x <- [1,2,3,4]]
mapIf p f = map (\x -> if p x then f x else x)
In addition to the answer of PiotrLegnica: Often, it's easier to read if you declare a helper function instead of using a lambda. Consider this:
map helper [1..4] where
helper x | even x = x `div` 2
| otherwise = x
([1..4] is sugar for [1,2,3,4])
If you want to remove all the other elements instead, consider using filter. filter removes all elements that don't satisfy the predicate:
filter even [1..4] -> [2,4]
So you can build a pipe of mapand filter than or use list-comprehension instead:
map (`div` 2) $ filter even [1..4]
[x `div` 2 | x <- [1..4], even x]
Choose whatever you like best.
Make your own helper function maker:
ifP pred f x =
if pred x then f x
else x
custom_f = ifP even f
map custom_f [..]
(caveat: I don't have access to a compiler right now. I guess this works OK...)
I like the other, more general solutions, but in your very special case you can get away with
map (\x -> x `div` (2 - x `mod` 2)) [1..4]
Mostly a rip off of existing answers, but according to my biased definition of "readable" (I like guards more than ifs, and where more than let):
mapIf p f = map f'
where f' x | p x = f x | otherwise = x
ghci says it probably works
ghci> let mapIf p f = map f' where f' x | p x = f x | otherwise = x
ghci> mapIf even (+1) [1..10]
[1,3,3,5,5,7,7,9,9,11]

Resources