1

I was looking through some prolog examples and stumbled upon http://www.anselm.edu/internet/compsci/faculty_staff/mmalita/HOMEPAGE/logic/bufalo.txt

first_names([keith,libby,margo,nora,otto]).
last_names([fell,grant,hall,ivey,jule]).
ages([2,3,4,5,6]).

start(Sol):- first_names(F),last_names(L),ages(A),
         Sol=[[F1,L1,A1],[F2,L2,A2],[F3,L3,A3],[F4,L4,A4],[F5,L5,A5]],
                F=[F1,F2,F3,F4,F5],             % if order is not important!
        member([libby,jule,_],Sol), % 1
        set_equal([L1,L2,L3,L4,L5],L),  % write correspondence
        set_equal([A1,A2,A3,A4,A5],A),
                member([keith,_,AgeK],Sol),     % 2
        member([_,ivey,AgeI],Sol),AgeK is AgeI+1,
        member([nora,_,AgeN],Sol),AgeI is AgeN+1,
        member([margo,_,AgeM],Sol),
        member([_,fell,AgeF],Sol),AgeF is 3+AgeM,
        member([otto,_,AgeO],Sol),member([_,hall,AgeH],Sol).

In this code example I have a general idea of how it works, but I'm really not sure on the specifics

I understand defining the hints as a list of atoms with the first field being first name, second field being last name, and third field being age with underscores showing missing information. However I'm not really sure why this is being called with member onto the Sol array. Not sure what it does in this context

Additionally, I don't really understand the purpose of the set_equal's and the F= in this code. It seems like it's setting three variables which are not referenced at all?

Thanks for your help!

false
  • 10,264
  • 13
  • 101
  • 209
user1066886
  • 202
  • 3
  • 12

1 Answers1

0

I've downloaded the code from the link you provide, to test with SWI-Prolog: there are a couple of syntactic problems in bibmm.pl, and at least set_equal/3 must change to:

set_equal([H|T],R):- member(H,R),select(H,R,Rez),set_equal(T,Rez).

After the correction, it does produce:

?- start(X).
X = [[keith, fell, 5], [libby, jule, 6], [margo, grant, 2], [nora, hall, 3], [otto, ivey, 4]] ;
X = [[keith, fell, 6], [libby, jule, 2], [margo, grant, 3], [nora, hall, 4], [otto, ivey, 5]] ;
X = [[keith, fell, 5], [libby, jule, 6], [margo, hall, 2], [nora, grant, 3], [otto, ivey, 4]] ;
X = [[keith, fell, 6], [libby, jule, 2], [margo, hall, 3], [nora, grant, 4], [otto, ivey, 5]] ;
X = [[keith, grant, 4], [libby, jule, 5], [margo, ivey, 3], [nora, hall, 2], [otto, fell, 6]] ;
X = [[keith, hall, 4], [libby, jule, 5], [margo, ivey, 3], [nora, grant, 2], [otto, fell, 6]] ;
false.

Now,

why this is being called with member onto the Sol array

member/2 will bind slots to to acceptable values, so the partially specified rows will get temptative values, and Prolog' backtracking will provide the search of appropriate permutations, that, as stated in bibmm.pl, are generated by set_equal/2.

About F=[...], I think it's just an aesthetic choice of the author, since F it's not used anymore in the start/1 procedure. Could be written as well as

start(Sol):- first_names([F1,F2,F3,F4,F5]),last_names(L),ages(A),
...

edit I didn't noticed, but there is a bug, namely, missing last constraint. After adding it

...
member([otto,_,AgeO],Sol),member([_,hall,AgeH],Sol),
AgeO is AgeH * 2.

the result is arguably better

?- start(X).
X = [[keith, fell, 5], [libby, jule, 6], [margo, hall, 2], [nora, grant, 3], [otto, ivey, 4]]
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • I'm not sure what that initial set_equal in your code does, could you break it down for me please? – user1066886 Nov 17 '14 at 14:05
  • it's not 'my code', I took it from the link you provided... anyway, it generates permutations, in a roundabound way, since we have permutations/2 in library(lists) – CapelliC Nov 17 '14 at 14:12