Implementatietechnieken voor logische programmeertalen Hoofdstuk 9: Implementatietechnieken voor logische programmeertalen
WAM: Warren Abstract Machine Prolog Assembler HNT WAM Vertolker Hardware
Registers P Programmawijzer CP Vervolgwijzer E Huidige omgeving B Huidig terugzoekpunt A Top van de stapel TR Top van het pad H Top van de hoop HB Hoopterugzoekpunt (H van B) S Structuurwijzer
Registers A1…An Argumentregisters X1…Xn Tijdelijke registers Y1…Yn Permanente registers
WAM Architectuur 1. De Stapel a. omgeving (cfr. stack frame) i. (Y1…Yn) (cfr. locale veranderlijken) ii. Een wijzer naar de continuatie (cfr. terugkeeradres) b. keuzepunt H, TR, B, CP, E, A1..An,
WAM Achitectuur 2. Hoop (heap) 3. Pad 4. Hulpstapel
Instructieklassen 1. get-instructies 2. put-instructies 3. unificatie-instructies 4. procedurale instructies 5. indexeringsinstructies
Feit zonder argumenten p. p/0: proceed P = CP
Twee feiten zonder argumenten p. p/0: try_me_else clause2, 0 proceed clause2: trust_me_else fail
Een aantal feiten zonder argumenten p/0: try_me_else clause2, 0 proceed clause2: retry_me_else clause3 clause3: retry_me_else clause4 clause4: trust_me_else fail p.
Een feit met een constante als argument p(a). p/1: get_constant a, A1 proceed
Twee feiten met constanten als argument p(a). p(b). p/1: switch_on_term Lv,Lc,fail,fail Lc: switch_on_constant 2, (a:const_a, b:const_b) Lv: try_me_else clause2, 1 const_a: get_constant a, A1 proceed clause2: trust_me_else fail const_b: get_constant b, A1
Verscheidene feiten met een constante als argument p(1). p(2). p(3). p/1: switch_on_term Lv,Lc,fail,fail Lc: switch_on_constant 3, (1:const_1,2:const_2,3:const_3) Lv: try_me_else clause2, 1 const_1: get_constant 1, A1 proceed clause2: retry_me_else clause3 const_2: get_constant 2, A1 clause3: trust_me_else fail const_3: get_constant 3, A1
Feiten met gestructureerde argumenten p(f(1)). p(f(2)). p/1: switch_on_term Lv,fail,fail,Ls Ls: switch_on_structure 1,(f/1:label_f) label_f: try f1, 1 trust f2 Lv: try_me_else clause2, 1 f1: get_structure f/1, A1 unify_constant 1 proceed clause2: trust_me_else fail f2: get_structure f/1, A1 unify_constant 2 f/1 1
Feiten met lijstargumenten p([1,2]). p([3,4]). p([1|[2|[]]]). p([3|[4|[]]]).
Feiten met lijstargumenten p/1: switch_on_term Lv, fail, Lli, fail Lli: try list1, 1 trust list2
Feiten met lijstargumenten Lv: try_me_else clause2, 1 list1: get_list A1 unify_constant 1 unify_variable X1 /* [2|[]] */ get_list X1 unify_constant 2 unify_nil proceed . 1 2 []
Feiten met lijstargumenten clause2: trust_me_else fail list2: get_list A1 unify_constant 3 unify_variable X1 /* [4|[]] */ get_list X1 unify_constant 4 unify_nil proceed
Voorbeeld p(f([1,Y],k(l))). p/1: get_stucture f/2, A1 unify_variable X1 /*[1,Y]*/ unify_variable X2 /*k(l)*/ get_list X1 unify_constant 1 unify_variable X1 /*[Y|[]]*/ unify_void 1 unify_nil get_structure k/1, X2 /*k(l)*/ unify_constant l proceed
Feiten met veranderlijken als argumenten p(X). p(Y). p/1: try_me_else clause2, 1 proceed clause2: trust_me_else fail
Gemengde argumenttypes p/1: switch_on_term Lv,Lc,Lli,Ls Ls: switch_on_structure 1, (f/1:label_f) label_f: try struct_f1, 1 trust struct_f2 Lc: switch_on_constant 2, (a:label_a, 2:label_2) Lv: try_me_else clause2, 1 label_a: get_constant a, A1 proceed clause2: retry_me_else clause3 label_2: get_constant 2, A1 p(a). p(2). p([a]). p(f(1)). p(f(2)).
Gemengde argumenttypes clause3: retry_me_else clause4 Lli: get_list A1 unify_constant a unify_nil proceed clause4: retry_me_else clause5 struct_f1: get_structure f/1, A1 unify_constant 1 clause5: trust_me_else fail struct_f2: get_structure f/1, A1 unify_constant 2 p(a). p(2). p([a]). p(f(1)). p(f(2)).
veranderlijken als argumenten p/1: try_me_else block2, 1 switch_on_term Lv, Lc, fail, fail Lc: switch_on_constant 2, (1: label_1, 2: label_2). Lv: try_me_else clause2, 1 label_1: get_constant 1, A1 proceed clause2: trust_me_else fail label_2: get_constant 2, A1 block2: retry_me_else block3 block3: retry_me_else block4 proceed block4: trust_me_else fail get_constant a, A1 p(1). p(2). p(X). p(Y). p(a).
Compilatie van regels P(…) :- Q(…). wordt gecompileerd tot verwerk de argumenten van P zet de argumenten voor Q klaar roep Q op
element(X,[Y|Z]) :- element(X,Z). Voorbeeld element(X,[Y|Z]) :- element(X,Z). element/2: get_list A2 unify_void 1 unify_variable A2 execute element/2 Staartoproep
Voorbeeld p(X,Y) :- q(X,Y). p/2: execute q/2
Voorbeeld p(X,Y) :- q(Y,X). p/2: get_variable X3,A1 put_value A2,A1 put_value X3,A2 execute q/2
complex doel in het antecedens main :- p(f([1,Y],k(l))). main/0: put_list X1 /*[_|_]*/ unify_void 1 /*[Y|_]*/ unify_nil /*[Y|[]]*/ put_list X2 /*[_|_]*/ unify_constant 1 /*[1|_]*/ unify_value X1 /*[1|[Y|[]]]*/ put_structure k/1,X3 /*k(_)*/ unify_constant l /*k(l)*/ put_structure f/2,A1 /*f(_,_)*/ unify_value X2 /*f([1|Y|[]]],_)*/ unify_value X3 /*f([1|Y|[]]],k(l))*/ execute p/1
Regel met verscheidene doelen in het antecedens P :- Q, R, S. allocate verwerk de argumenten P zet de argumenten van Q klaar call Q, M zet de argumenten van R klaar call R, M1 zet de argumenten van S klaar deallocate execute S
Voorbeeld p(X,Y):- q1(X), q2(Y), q3(X,Y). p/2: allocate get_variable Y1,A1 get_variable Y2,A2 call q1/1, 2 put_value Y2,A1 call q2/1, 2 put_value Y1,A1 put_value Y2,A2 deallocate execute q3/2
Alternatieve implementatiemethoden 1. Op het Prologniveau 2. Op het WAM niveau 3. Op het niveau van codegeneratie 4. Op het hardwareniveau
Op het Prologniveau 1. Abstracte interpretatie 2. Binarisatie
Binarisatie p(X,[X|Y]). p(X,[Y|Z]) :- q(Z), p(X,Z). q([_|_]). wordt vertaald naar p(X,[X|Y],C):- call(C). p(X,[Y|Z],C):- q(Z,p(X,Z,C)). q([_|_],C) :- call(C).
Uitvoering gebinariseerd programma p(2,[1,2,3],true) q([2,3],p(2,[2,3],true)) call(p(2,[2,3],true)) p(2,[2,3],true) call(true) true
Op het WAM-niveau Samennemen van instructies unify_list = unify_variable + get_list Primitiever maken van instructies (afsplitsen van deref) Dataflowanalyse om typecontroles te vermijden
Op het niveau van codegeneratie Compilatie naar assembler of naar C
Op het hardwareniveau WAM-chips (LISP chips)
Prestatiemetingen LIPS = aantal call en execute-instructies nrev([],[]). nrev([X|L],R) :- nrev(L,L1), append(L1,[X],R). append([],L,L). append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs).
Prestatiemetingen Logische inferenties: n(0) = 1 n(L) = 1 + n(L-1) + a(L-1), L>0 a(0) = 1 a(L) = 1 + a(L-1), L > 0
Gesloten uitdrukking Reductie van f (n) geeft
Resultaat
Accumulatorversie rev(L1,L2) :- rev(L1,[],L2). rev([],R,R). rev([X|L],A,R) :- rev(L,[X|A],R). n(L) = 2 + L
Naïef sorteeralgoritme permsort(L,R) :- perm(L,R), sorted(R). perm([],[]). perm([X|Xs],Zs) :- perm(Xs,Ys), insert(X,Ys,Zs).
Naïef sorteeralgoritme insert(X,Ys,[X|Ys]). insert(X,[Y|Ys],[Y|Zs]) :- insert(X,Ys,Zs). sorted([]). sorted([_]). sorted([X,Y|Z]) :- X=<Y, sorted([Y|Z]).
straat([huis(1,N1,P1,D1,A1,C1), huis(2,N2,P2,D2,A2,C2), huis(3,N3,P3,D3,A3,C3), huis(4,N4,P4,D4,A4,C4), huis(5,N5,P5,D5,A5,C5)]). solve(X,Y) :- straat(Straat), voorwaarde(huis(_,english,red,_,_,_),Straat), voorwaarde(huis(_,spanish,_,_,dog,_),Straat), voorwaarde(huis(_,_,green,coffee,_,_),Straat), voorwaarde(huis(_,_,_,_,chicken,camel),Straat), voorwaarde(huis(_,ukraine,_,tea,_,_),Straat), voorwaarde(huis(N1,_,green,_,_,_),Straat), voorwaarde(huis(N2,_,white,_,_,_),Straat), buren(N1,N2), voorwaarde(huis(_,_,yellow,_,_,lord),Straat), voorwaarde(huis(3,_,_,milk,_,_),Straat),
voorwaarde(huis(1,norway,_,_,_,_),Straat), voorwaarde(huis(M1,_,_,_,_,marlboro),Straat), voorwaarde(huis(M2,_,_,_,fox,_),Straat), buren(M1,M2), voorwaarde(huis(K1,_,_,_,_,lord),Straat), voorwaarde(huis(K2,_,_,_,horse,_),Straat), buren(K1,K2), voorwaarde(huis(_,_,_,wine,_,hb),Straat), voorwaarde(huis(_,japanese,_,_,_,luckystrike),Straat), voorwaarde(huis(L1,norway,_,_,_,_),Straat), voorwaarde(huis(L2,_,blue,_,_,_),Straat), buren(L1,L2), voorwaarde(huis(_,X,_,water,_,_), Straat), voorwaarde(huis(_,Y,_,_,elefant,_), Straat). voorwaarde(X,[X|_]). voorwaarde(X,[_|L]) :- voorwaarde(X,L). buren(N1,N2) :- N1 is N2 + 1. buren(N1,N2) :- N2 is N1 + 1.
/******************************** BinProlog 3.00 Copyright (C) Paul Tarau, 1992-93 by FTP from: clement.info.umoncton.ca E-MAIL to : binprolog@info.umoncton.ca begin loading wam.bp......finished loading ?- [houses]. compiling(to(mem),houses.pl,...) compile_time(220) ?- solve(X,Y). X=norway, Y=japanese; no ***********************************/