pv@lln-cs.UUCP (Patrick Vandamme) (09/04/86)
I am testing the `famous' Turbo Prolog Software and, after all the good things that I heard about it, I was very surprised at having problems with the first large program I tried. I give here this program. It finds all the relations between a person and his family. But for some people, it answers with a lot of strange characters. I think there must be a dangling pointer somewhere. Note that this happens only with large programs ! Have someone the same result ? (for the stange characters, try with "veronique"). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* +-----------------------------------------------------+ | Programme de gestion d'une base de donnees | | de relations familiales. | +-----------------------------------------------------+ P. Vandamme - Unite Info - UCL - Aout 1986 */ domains nom = string noms = nom* couple = integer relation = string distance = real chemin = relation* qqn = qqn(nom,distance,chemin) famille = qqn* predicates /* base de donnees */ couple(couple,nom,nom) homme(couple,nom) femme(couple,nom) /* relations familiales */ etre(couple,nom) en_couple(couple,nom) conjoint(nom,nom) parent_de(nom,nom) frere_de(nom,nom) soeur_de(nom,nom) frere_ou_soeur_de(nom,nom) R(nom,relation,nom,distance) /* programmes */ pgm repeat imprimer_famille(nom,famille) imprimer_chemin(chemin) entourage(nom,famille) entourage1(nom,qqn) explorer_famille(famille,famille,famille) referer_entourage(qqn,famille,famille) integrer_entourage(famille,famille,famille,famille,famille) integrer_qqn(qqn,famille,famille,famille,famille) equal_qqn(qqn,qqn) inclure_qqn(qqn,famille,famille) extraire_qqn(nom,famille,famille,qqn,famille) qqn_minimum(qqn,qqn,qqn) append_famille(famille,famille,famille) append_chemin(chemin,chemin,chemin) goal pgm. clauses /* BASE DE DONNEES */ couple(01,"tom","natacha"). couple(02,"luc","lennie"). couple(03,"robert","veronique"). couple(04,"henri","renee"). couple(05,"charles","xiao-lou"). couple(06,"manu","brigitte"). couple(07,"marc","geraldine"). couple(08,"francis","anne-marie"). couple(09,"pierre","marie-louise"). homme(00,"henri"). homme(00,"pierre"). homme(00,"manu"). homme(06,"charles"). homme(03,"luc"). homme(03,"tom"). homme(04,"marc"). homme(08,"philippe"). homme(09,"robert"). homme(09,"francis"). homme(09,"jacques"). femme(00,"lennie"). femme(00,"xiao-lou"). femme(00,"geraldine"). femme(00,"veronique"). femme(00,"renee"). femme(00,"anne-marie"). femme(00,"marie-louise"). femme(00,"brigitte"). femme(02,"katrina"). femme(06,"natacha"). femme(08,"anne-christine"). femme(08,"louise"). femme(08,"marielle"). femme(09,"monique"). /* RELATIONS FAMILIALES */ etre(C,X) :- homme(C,X). etre(C,X) :- femme(C,X). en_couple(C,X) :- couple(C,X,_). en_couple(C,X) :- couple(C,_,X). conjoint(X,Y) :- couple(_,X,Y). conjoint(X,Y) :- couple(_,Y,X). parent_de(X,Y) :- etre(C,X), C <> 0, en_couple(C,Y). frere_de(X,Y) :- etre(C,X), C <> 0, homme(C,Y), X <> Y. soeur_de(X,Y) :- etre(C,X), C <> 0, femme(C,Y), X <> Y. frere_ou_soeur_de(X,Y) :- frere_de(X,Y). frere_ou_soeur_de(X,Y) :- soeur_de(X,Y). R(X,"mari de",Y,1) :- couple(_,X,Y). R(X,"femme de",Y,1) :- couple(_,Y,X). R(X,"frere de",Y,1) :- frere_de(Y,X). R(X,"soeur de",Y,1) :- soeur_de(Y,X). R(X,"mere de",Y,1) :- couple(C,_,X), etre(C,Y). R(X,"pere de",Y,1) :- couple(C,X,_), etre(C,Y). R(X,"grand mere de",Y,2) :- R(X,"mere de",Z,_), parent_de(Y,Z). R(X,"grand pere de",Y,2) :- R(X,"pere de",Z,_), parent_de(Y,Z). R(X,"fils de",Y,1) :- homme(C,X), C <> 0, en_couple(C,Y). R(X,"fille de",Y,1) :- femme(C,X), C <> 0, en_couple(C,Y). R(X,"petit fils de",Y,2) :- R(X,"fils de",Z,_), parent_de(Z,Y). R(X,"petite fille de",Y,2) :- R(X,"fille de",Z,_), parent_de(Z,Y). R(X,"beau fils de",Y,2) :- couple(_,X,Z), parent_de(Z,Y). R(X,"belle fille de",Y,2) :- couple(_,Z,X), parent_de(Z,Y). R(X,"beau frere de",Y,2) :- frere_de(Z,X), conjoint(Z,Y). R(X,"beau frere de",Y,2) :- couple(_,X,Z), soeur_de(Y,Z). R(X,"belle soeur de",Y,2) :- soeur_de(Z,X), conjoint(Z,Y). R(X,"belle soeur de",Y,2) :- couple(_,Z,X), frere_de(Y,Z). R(X,"oncle de",Y,2) :- frere_de(Z,X), parent_de(Y,Z). R(X,"tante de",Y,2) :- soeur_de(Z,X), parent_de(Y,Z). R(X,"neveu de",Y,2) :- R(X,"fils de",Z,_), frere_ou_soeur_de(Y,Z). R(X,"niece de",Y,2) :- R(X,"fille de",Z,_), frere_ou_soeur_de(Y,Z). R(X,"cousin de",Y,3) :- R(X,"fils de",W,_), frere_ou_soeur_de(W,Z), parent_de(Y,Z). R(X,"cousine de",Y,3) :- R(X,"fille de",W,_), frere_ou_soeur_de(W,Z), parent_de(Y,Z). /* PROGRAMMES */ pgm :- makewindow(1,7,7," FAMILLE ",0,0,25,80), repeat, clearwindow, nl, write(" Nom d'une personne ? "), readln(Nom), nl, explorer_famille([qqn(Nom,0,[])],[],Famille), imprimer_famille(Nom,Famille), readchar(_), fail. repeat. repeat :- repeat. imprimer_famille(_,[]) :- !. imprimer_famille(N,[qqn(Nom,_,Chemin)|Famille]) :- write(" ",N," est "), imprimer_chemin(Chemin), write(Nom), nl, imprimer_famille(N,Famille). imprimer_chemin([]) :- !. imprimer_chemin([Rel|Chemin]) :- write(Rel," "), imprimer_chemin(Chemin). /* entourage(Nom,Famille) ---------------------- Permet de trouver l'ensemble des personnes qui ont une relation directe avec Nom. */ entourage(Nom,Famille) :- findall(Qqn,entourage1(Nom,Qqn),Famille). entourage1(Nom,qqn(Y,Distance,[A])) :- R(Nom,A,Y,Distance). /* explorer_famille(Famille,[],NewFamille) --------------------------------------- Permet d'explorer toute la famille, en recherchant successivement les entourages de tous les Qqn dans la famille. */ explorer_famille([],Famille,Famille) :- !. explorer_famille([Qqn|L_Qqn],Famille,Result) :- equal_qqn(Qqn,qqn(Nom,_,_)), write(" ",Nom,"\n"), entourage(Nom,Entourage), referer_entourage(Qqn,Entourage,NewEntourage), integrer_entourage(NewEntourage,L_Qqn,Famille,NewL_Qqn,NewFamille), explorer_famille(NewL_Qqn,[Qqn|NewFamille],Result). /* referer_entourage(Qqn,Entourage,NewEntourage) ------------------------------------------------ Permet de mettre a jour les chemins et distances de l'Entourage, en fonction de Qqn. */ referer_entourage(_,[],[]) :- !. referer_entourage(Qqn,[qqn(N,D,C)|Ent],[qqn(N,NewD,NewC)|NewEnt]) :- referer_entourage(Qqn,Ent,NewEnt), equal_qqn(Qqn,qqn(_,Dist,Chem)), NewD = Dist + D + 0.01, append_chemin(Chem,C,NewC). /* integrer_entourage(Entourage,Work,Famille,NewWork,NewFamille) ------------------------------------------------------------- Permet de distribuer Entourage dans les ensembles appropries. (cfr. integrer_qqn). */ integrer_entourage([],Work,Famille,Work,Famille) :- !. integrer_entourage([Qqn|Entourage],Work,Famille,NewWork,NewFamille) :- integrer_qqn(Qqn,Work,Famille,W,F), integrer_entourage(Entourage,W,F,NewWork,NewFamille). /* integrer_qqn(Qqn,Work,Famille,NewWork,NewFamille) ------------------------------------------------- Permet de placer Qqn dans l'ensemble approprie. S'il existe deja dans Famille, on le laisse la en gardant la distance minimum. Sinon on l'inclu dans Work. */ integrer_qqn(Qqn1,Work,Famille,Work,[QqnMin|NewFamille]) :- equal_qqn(Qqn1,qqn(Nom,_,_)), extraire_qqn(Nom,Famille,[],Qqn2,NewFamille), qqn_minimum(Qqn1,Qqn2,QqnMin), !. integrer_qqn(Qqn,Work,Famille,NewWork,Famille) :- inclure_qqn(Qqn,Work,NewWork). equal_qqn(Qqn,Qqn). /* inclure_qqn(Qqn,Famille,NewFamille) ----------------------------------- Permet d'ajouter Qqn dans une famille de relations. Si ce Qqn n'existe pas, il est simplement ajoute dans la liste. S'il existe deja, on compare les deux distances et on garde la relation ayant la distance minimale. */ inclure_qqn(Qqn1,Famille,[QqnMin|NewFamille]) :- equal_qqn(Qqn1,qqn(Nom,_,_)), extraire_qqn(Nom,Famille,[],Qqn2,NewFamille), qqn_minimum(Qqn1,Qqn2,QqnMin), !. inclure_qqn(Qqn,Famille,[Qqn|Famille]). /* extraire_qqn(Nom,Famille,[],Qqn,NewFamille) ------------------------------------------- Permet d'enlever Qqn dont on connait le Nom. Si ce Qqn n'existe pas, ce predicat fail. Sinon, il renvoie ce Qqn et la nouvelle famille. */ extraire_qqn(_,[],_,_,_) :- !, fail. extraire_qqn(Nom,[Qqn|L_Qqn],Work,Qqn,NewFamille) :- equal_qqn(Qqn,qqn(Nom,_,_)), append_famille(L_Qqn,Work,NewFamille), !. extraire_qqn(Nom,[Qqn|L_Qqn],Work,S1,S2) :- extraire_qqn(Nom,L_Qqn,[Qqn|Work],S1,S2). /* append_famille(Famille1,Famille2,NewFamille) -------------------------------------------- Permet de concatener deux familles. */ append_famille([],Famille,Famille). append_famille([Qqn|F1],F2,[Qqn|F3]) :- append_famille(F1,F2,F3). /* append_chemin(Chemin1,Chemin2,NewChemin) -------------------------------------------- Permet de concatener deux chemins. */ append_chemin([],Chemin,Chemin). append_chemin([Qqn|F1],F2,[Qqn|F3]) :- append_chemin(F1,F2,F3). /* qqn_minimum(Qqn1,Qqn2,QqnMinimum) --------------------------------- Permet de trouver le Qqn minimum entre deux Qqn. */ qqn_minimum(Qqn1,Qqn2,Qqn1) :- equal_qqn(Qqn1,qqn(_,Dist1,_)), equal_qqn(Qqn2,qqn(_,Dist2,_)), Dist1 <= Dist2, !. qqn_minimum(_,Qqn,Qqn). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Patrick Vandamme Unite d'Informatique UUCP : (prlb2)lln-cs!pv Universite Catholique de Louvain Phone: +32 10 43 24 15 Place Sainte-Barbe, 2 Telex: 59037 UCL B B-1348 Louvain-La-Neuve Eurokom: Patrick Vandamme UCL Belgium Fax : +32 10 41 56 47
clh@cbrma.UUCP (C.Harting) (09/09/86)
I purchased Turbo Prolog Friday night, and immediately tried to compile the GeoBase program on my Tandy 1000 (384K). I could not even create a .OBJ file on my machine, so I compiled it on a 640K AT&T PC6300. Caveat No. 1: large programs need large amounts of memory. I compiled Patrick's "programme de gestion" to disk and it ran flawlessly (I think -- this is my first lesson in French!). BUT when compiled to memory, I got the same errors as Patrick. Caveat No. 2: compile large programs to disk and run standalone. And, Caveat No. 3: leave out as many memory-resident programs as you can stand when booting the machine to run Turbo Prolog. 'Nuff said? =============================================================================== Chris Harting "Many are cold, few are frozen." AT&T Network Systems Columbus, Ohio The Path (?!?): cbosgd!cbrma!clh
john@uwmacc.UUCP (John Jacobsen) (09/11/86)
> Xref: uwmacc net.ai:1941 net.lang.prolog:528 > Summary: How to get around it. I got the "Programme de Gestion de Base de Donnees" to work fine... on an AT with a meg of memory. I think Patrick Vandamme just ran out of memory, cause his code is immaculate. John E. Jacobsen University of Wisconsin -- Madison Academic Computing Center