1 / 19

Meta-interpreters

Meta-interpreters. Interpreted languages like Prolog can easily treat program code as data can use ‘clause’ to look at program code assert, retract, abolish to create/remove code =.., name, etc to look at terms themselves meta-programming: a program which treats program code as data

cargan
Download Presentation

Meta-interpreters

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Meta-interpreters COSC 2P93 Prolog: Meta-interpreters • Interpreted languages like Prolog can easily treat program code as data • can use ‘clause’ to look at program code • assert, retract, abolish to create/remove code • =.., name, etc to look at terms themselves • meta-programming: a program which treats program code as data • the program code executed can be a different language than the code the meta-program is written in • or it can be the same language • meta-interpreter: a meta-program that executes a program(“source program”) , possibly written in that language itself • can be used to enhance your language execution • can create prototype languages as well • Prolog is extremely useful for meta-programming

  2. User-defined operators COSC 2P93 Prolog: Meta-interpreters • op(Precedence, Code, Op). • Precedence: numeric code indicating binding strength of operator • smaller number = higher binding • used when parentheses are missing • Code: position and associativity • prefix: fx, fy • postfix: xf, yf • infix: xfx, xfy, yfx, yfy • “x”: argument must have ops of lower precedence • “y”: argument must have ops of equal or lower precedence • Op: characters for operator

  3. User-defined operators COSC 2P93 Prolog: Meta-interpreters Example: ?- op(470, fy, 'not'). % prefix, binds strongest ?- op(475, xfy, 'and'). % infix, binds stronger than ‘or’ ?- op(480, xfy, 'or'). % infix can then write: not a and b or not c --> ((not a) and b) or (not c) regular structure form: or( and( not(a), b ), not(c) )

  4. Meta-interpreter COSC 2P93 Prolog: Meta-interpreters • Example: a meta-interpreter for pure Prolog solve( true ) :- !. solve( not P ) :- !, \+ solve(P). solve( (P, Q) ) :- !, solve(P), solve(Q). solve( P ) :- clause(P, Body), solve(Body). • each clause catches one possible case • ‘true’ is used to represent the termination of a branch of execution • note that clause(P, Body) returns P=parent(mary, bob), B=true for the fact: parent(mary, bob). • the case for (P, Q) breaks up multiple goals; “,” is simply a built-in infix operator • eg. solve((A, B, C, D)) = solve(P, Q) --> P = A, Q = (B, C, D) etc • the cuts are needed so that, during backtracking, true, not P, and (P,Q) won’t be executed by the final case that uses clause

  5. Meta-interpreters COSC 2P93 Prolog: Meta-interpreters • The bulk of the work is done by ‘clause’ • clause actually does the unification of the current goal P with a clause • upon backtracking, clause will backtrack and unify P with the next clause • Note that, when P is unified with the clause Q :- B, the variable substitutions obtained via P=Q are automatically applied to B • The interesting part of meta-interpreters is that you can alter the language behaviour • Example: a meta-interpreter that selects goals from right-to-left solve( true ) :- !. solve( not P ) :- !, \+ solve(P). solve( (P, Q) ) :- !, solve(Q), solve(P). solve( P ) :- clause(P, Body), solve(Body).

  6. Meta-interpreters COSC 2P93 Prolog: Meta-interpreters • Example: A meta-interpreter that doesn’t do any backtracking solve( true ) :- !. solve( not P ) :- !, \+ solve(P). solve( (P, Q) ) :- !, solve(P), solve(Q). solve( P ) :- clause(P, Body), !, solve(Body). • Example: adding some built-in predicates (no longer pure Prolog) solve( true ) :- !. solve( not P ) :- !, \+ solve(P). solve( (P, Q) ) :- !, solve(P), solve(Q). solve( write(X) ) :- !, write(X). solve( read(X) ) :- !, read(X). solve( P ) :- clause(P, Body), solve(Body).

  7. Meta-interpreters COSC 2P93 Prolog: Meta-interpreters • Example: print out a trace of your execution solve( true ) :- !. solve( not(P) ) :- !, \+ solve(P). solve( (P, Q) ) :- !, solve(P), solve(Q). solve( P ) :- (write(‘calling ‘), write(P) ; write(P), write(‘fails’), nl, !, fail), clause(P, Body), write(‘...succeeds’), nl, solve(Body).

  8. Meta-interpreters COSC 2P93 Prolog: Meta-interpreters • By creating new operators, you can even change the syntax of the source program -- great for creating a new language • Example: a new syntax for Prolog ?- op(700, xfy, and). ?- op(800, xfx, if). solve( true ) :- !. solve( not P ) :- !, \+ solve(P). solve( P and Q ) :- !, solve(P), solve(Q). solve( P ) :- P if Body, solve(Body). grandmother(X, Y) if mother(X, Z) and mother(Z, Y). • Note how ‘if’ is just another predicate name: • same as: if(grandmother(X,Y), (mother(X,Z), mother(Z,Y)). • we essentially let the meta-level Prolog do the backtracking for us!

  9. Metainterpreters COSC 2P93 Prolog: Meta-interpreters • Example: a metainterpreter that constructs a logical proof tree solve(true, true) :- !. solve(not P, (not Proof)) :- !, \+ solve(P, Proof). solve((P, Q), (ProofP, ProofQ)) :- !, solve(P, ProofP), solve(Q, ProofQ). solve(P, (P <== ProofP)) :- clause(P, Body), solve(Body, ProofP). • arg 2 contains pattern of proof • Would be nice to print it out in a legible form...

  10. Metainterps COSC 2P93 Prolog: Meta-interpreters prettyprint(E) :- prettyprint2(E, 0). prettyprint2(not A, Indent) :- !, nl, tab(Indent), write('NOT '), prettyprint2(A, Indent). prettyprint2((A,B), Indent) :- !, prettyprint2(A, Indent), nl, tab(Indent), write('AND'), prettyprint2(B, Indent). prettyprint2(A <== true, Indent) :- !, nl, tab(Indent), write(A), write(' <== TRUE').

  11. Prettyprint (cont) COSC 2P93 Prolog: Meta-interpreters prettyprint2(A <== P, Indent) :- !, nl, tab(Indent), write(A), write(' <== '), Indent2 is Indent+3, prettyprint2(P, Indent2). prettyprint2(A, Indent) :- nl, tab(Indent), write(A).

  12. Another metainterpreter: “C” COSC 2P93 Prolog: Meta-interpreters • This example interprets a C-like language. • Grammar of language (Backus-Naur Form, or BNF): E ::= V := A | E;E | if(B, E, E) | while(B, E) A ::= var | const | A+A | A-A | A*A B ::= true | false | A>A | A=A | A>=A • Implement via operators (“:=“, “;”) and structures: if(B, E, F) and while(B, E) • Memory: list of variable/value pairs: • [(a, 0), (flag, 1), (value, 2014), ...]

  13. C metainterpreter: “interp3” COSC 2P93 Prolog: Meta-interpreters • Idea: each statement in language affects the state of memory • To interpret a program, determine how each statement changes memory • This is an “operational semantics” approach. eg. memory before: [(a, 1), (b, 2), (c, 5)] a := b*c memory after: [(a, 10), (b, 2), (c, 5)] eg. E1;E2 where initial memory = Mem1 interpret(E1, Mem1) to generate Mem2 then interpret (E2, Mem2) to generate MemFinal eg. while(B, E): let init memory = Mem1 if B = true then interpret(E, Mem1) to create Mem2 and interpret(while(B, E), Mem2) to create MemF

  14. interp3 code examples COSC 2P93 Prolog: Meta-interpreters ?- op(600, xfy, ':='). interp( (Var := A), Init, Final ) :- interpArith(A, Init, Val), assign(Var, Val, Init, Final). % assign(Var, Val, Before, After): % replaces current (Var, OldVal) pair in with new (Var, Val) pair. assign(Var, Val, MemBefore, MemAfter) :- append(A, [(Var, _)|B], MemBefore), append(A, [(Var,Val)|B], MemAfter), !. assign(Var, _, _, _) :- !, write('Error in assignment: '), write(Var), write(' not found.'), nl, fail.

  15. interp3 COSC 2P93 Prolog: Meta-interpreters interp( (E;F), Init, Final ) :- !, interp(E, Init, Tmp), interp(F, Tmp, Final). interp( if(B, E, F), Init, Final ) :- !, (interpBool(B, Init) -> interp(E, Init, Final) ; interp(F, Init, Final)).

  16. interp3 COSC 2P93 Prolog: Meta-interpreters interp( while(B, E), Init, Final) :- !, (interpBool(B, Init) -> interp(E, Init, Tmp), interp( while(B, E), Tmp, Final) ; Init = Final).

  17. interp3: arithmetic COSC 2P93 Prolog: Meta-interpreters interpArith(A, _, A) :- integer(A), !. interpArith(V, Init, Val) :- member((V,Val), Init), !. interpArith(A+B, Init, Val) :- interpArith(A, Init, ValA), interpArith(B, Init, ValB), Val is ValA + ValB, !. % similar for -, *, ...

  18. interp3: boolean COSC 2P93 Prolog: Meta-interpreters interpBool(true, _) :- !. interpBool(false, _) :- !, fail. interpBool(A > B, Init) :- interpArith(A, Init, ValA), interpArith(B, Init, ValB), !, ValA > ValB.

  19. interp3 COSC 2P93 Prolog: Meta-interpreters ?- test(A,B,C). A = (a:=2;b:=3;a:=4), B = [(a,0),(b,0),(c,0)], C = [(a,4),(b,3),(c,0)] A = (a:=2+1;b:=10-a;if(a>b+a,c:=5,c:= -5)), B = [(a,0),(b,0),(c,0)], C = [(a,3),(b,7),(c,-5)] A = (a:=2;b:=10;c:=1;while(b>0,(c:=c*a;b:=b-1))), B = [(a,0),(b,0),(c,0)], C = [(a,2),(b,0),(c,1024)]

More Related