Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!jarthur!nntp-server.caltech.edu!gumby!newton From: newton@gumby.cs.caltech.edu (Mike Newton) Newsgroups: comp.lang.prolog Subject: Re: general data structures are impossible Message-ID: Date: 15 Feb 91 12:12:40 GMT Sender: news@nntp-server.caltech.edu Organization: California Institute of Technology, Pasadena Lines: 105 Nntp-Posting-Host: gumby.cs.caltech.edu [this was copied/input by mouse from another system, pardon any typos.... ] %% Andre' Marien's beautiful example of the partners program had a few %% problems if not called just right. I've made it a little more general %% and added a few comments.... %% %% (Note that it doesnt take Prolog III to run this... SICStus ran it fine.) %% %% - mike (newton@gumby.cs.caltech.edu) %% %% ---------------- snip snip ---------------- /* 91.2.14, Andre' Marien, bimandre@cs.kuleuven.ac.be, Author */ /* * 91.2.15, Mike Newton, newton@gumby.cs.caltech.edu: * Original version had some serious errors if you wanted to add people * ''in the future''. See the example people 'spam', 'tuna', 'mort' and * 'mindy' in the test predicate. Runs under SICStus... [uses nonvar/1]. */ /* register_person/3 -- add new entry to db w/o creating duplicates */ register_person(P,L,L) :- member_chk(P,L), ! . register_person(P,L,[P|L]) . write_person(P) :- name_person(P,NN), age_person(P,AN), ref_partner(P,S), name_person(S,NS), age_person(S,AS), write(name = NN), nl, write(' age' = AN), nl, write(' partner' = NS), nl, write(' partner age' = AS), nl . /* N,S,A == name, significant_other, age */ name_person(p(N,_S,_A),N) . ref_partner(p(_N,S,_A),S) . age_person(p(_N,_S,A),A) . p(L,a(NN,NS,NA),NL) :- name_person(PS,NS), /* build up new Partner: PS = p(NS, PN, _) */ ref_partner(PS,PN), /* PN becomes record of PS and ... */ name_person(PN,NN), /* build up Newuser: PN = p(NN, PS, NA) */ ref_partner(PN,PS), /* ... PS becomes record of PN */ age_person(PN,NA), register_person(PN,L,TL), register_person(PS,TL,NL), write('added:'), nl, write_person(PN)/* more */, /* as received by news, this had */ /* write_person(PN)more, */ nl . p(L,n(NN),NL) :- name_person(PN,NN), register_person(PN,L,NL), write_person(PN), nl . /* * check memberbership. note that a var as a name should instantly fail * so that we create a new record (which will later become instantiated). */ member_chk(p(N,_,_),_) :- var(N), !, fail. /* can be eliminated */ member_chk(X,[Y|L]) :- /* by a nonvar test here */ member_chk(X,Y,L) . /* assumes names are unique -- MON */ /* * note we can't unify either of N, or S in the head, as * subterms (infinite) may cause infinite hassle! */ member_chk(p(N1,S1,A), p(N2,S2,A),_L) :- nonvar(N1), nonvar(N2), N1 = N2, S1 = S2, ! . member_chk(X,_,[Y|L]) :- member_chk(X,Y,L) . test :- p([],a(john,jane,22),L1), p(L1,a(jane,john,21),L2), p(L2,a(mark,mia,60),L3), p(L3,a(mia,mark,18),L4), /* added ... -- MON */ p(L4,a(spam,_,25),L5), p(L5,a(tuna,spam,34),L6), p(L6,a(mindy,_,30),L7), p(L7,a(_,mindy,-34),L8), /* mindy's partner is -34 */ p(L8,a(mort,mindy,_),L), /* and its a mort */ p(L,n(tuna),_), p(L,n(spam),_), p(L,n(mindy),_), p(L,n(mort),_), /* ... added -- MON */ p(L,n(john),_), p(L,n(jane),_), p(L,n(mark),_), p(L,n(mia),_) .