Michael Codish and Harald Søndergaard
still to do
ackermann(0,N,s(N)). ackermann(s(M),0,Res) :- ackermann(M,s(0),Res). |
ackermann(s(M),s(N),Res) :- ackermann(s(M),N,Res1), ackermann(M,Res1,Res). |
my_clause(ack(0,N,s(N)), []). my_clause(ack(s(M),0,Res), [ack(M,s(0),Res)]). my_clause(ack(s(M),s(N),Res), [ack(s(M),N,Res1),ack(M,Res1,Res)]).
The predicate load_file in the program input.pl will read the clauses from a file and assert the corresponding my_clause representation to the Prolog database.
To support flexibility in the interpretation of unification we make unification explicit when reading in the program. For example the clause,
ackermann(s(M),0,Res) :- ackermann(M,s(0),Res).is represented internally (in my_clause representation) as
ackermann(A,B,C) :- unify(A,s(M)), unify(B,0), unify(C,Res), unify(D,M), unify(E,s(0)), unify(F,Res), ackermann(D,E,F).This can be done when inputting the program's clauses by the predicate load_file in the program input_normalize.pl
The usual interpretation of unification is defined by
unify(X,Y) :- X=YMaking unification explicit gives a first step towards obtaining an analyser. In the paper we discuss why this is not sufficient and use the ackermann function as an example. The unification for the (extended) parity domain described in the paper (click to recall the definition) is defined by ( Figure 2 in the paper)
The simple concrete interpreter of Figure 1 (in the paper) is then enhanced to interpret the unify/2 predicate. The interpreter involves the following modules:
For an example run of the interpreter on the two domains for the Ackermann example check here.
The interpreter for this semantics is not presented in the paper. We demonstrate it here using a naive fixed point engine. The minimal model is constructed based on the alphabet of the program.
For an example run of the interpreter check here.
Theinterpreter is presented in the paper as Figure 3.
We demonstrate an interpreter applying the naive evaluation strategy.
Facts that have been proven already are maintained in the Prolog database. The engine is based on the concept that we should prove (in all possible ways) the body of a clause using facts derived in previous iterations and assert the head if it is new.
The engine uses the following modules:
For an example run of the interpreter check here.
The standard semantics makes answers observable. We enhance the semantics (and the interpreters) to make observable also the calls encountered during a computation and the computation state at program points. This results in a goal dependent semantics (in contrast to the previous goal independent definitions).
To make calls observable, conceptually, we use a combination of bottom-up evaluation with magic sets transformation. However in practice this is done using an interpreter which combines the two and interprets the given program directly. Such an interpreter is said to induce the magic set transformation.
The interpreter is given as
Running the interpreter requires the user to specify bot the program and the initial query.
For an example run of the interpreter check here.
my_clause
representation.
The fact that q is thejth
atom in the ith clause is represented by an atom of the
form pp(i,j,q)
.
For example, the following program to rotate the
elements of a list:
rotate(Xs,Ys) :- append([],Ys,Ys). append(As,Bs,Xs), append([X|Xs],Ys,[X|Zs]) :- append(Bs,As,Ys). append(Xs,Ys,Zs).is represented internally as:
my_clause(rotate(Xs,Ys),[pp(1,1,append(As,Bs,Xs)),pp(1,2,append(Bs,As,Ys))]). my_clause(append([],Ys,Ys),[]). my_clause(append([X|Xs],Ys,[X|Zs]),[pp(3,1,append(Xs,Ys,Zs))]).
The changes to the interpreter are then minimal. We demonstrate an interpreter which notes the calls at each program point.
We demonstrate how the operations in the concrete interpreter can be replaced by abstract operations and an abstract interpreter is obtained. The various unification operations and the various lub operations have been collected together in unification_operations.pl and lub_operations.pl respectively. The basic idea is to make unification explicit (the same as demonstrated above using the predicate load_file in the program input_normalize.pl and to enhance the bottom-up interpreter accordingly.
The interpreter is given as tp_abs.pl. The evaluation for the ackermann program using the unification algorithm for the enhanced parity domain (click to recall the definition) defined in ( Figure 2 of the paper), gives
ack(zero, zero, one) ack(even, zero, odd) ack(zero, one, even) ack(even, one, odd) ack(zero, even, odd) ack(even, even, odd) ack(zero, odd, even) ack(even, odd, odd) ack( one, zero, even) ack( odd, zero, odd) ack( one, one, odd) ack( odd, one, odd) ack( one, even, even) ack( odd, even, odd) ack( one, odd, odd) ack( odd, odd, odd)
Note that this output exposes non-trivial parity dependencies
amongst the arguments of ack
. For example, the last
column on the right tells us that ack(i,j) is indeed odd (and greater
than 1) for all i>1.
The example run of the interpreter for this example is given here (the query to the analyzer specifies the program and the domain).
We illustrate three interpreters: for goal independent analysis; for goal dependent analysis (with program points); and for goal dependent analysis (ignoring program points);
the following modules are used:
Here are a few examples of running the interpreter:
This example highlights the property that ackermann's function is always odd for arguments greater than 1.
For more details on the application of pattern analysis to structure untupling see here.
program: hanoi and its abstract minimal model: hanoi.depthk.
program: hanoi and its abstract minimal model for the parity domain: plus.parity
These analysers use the same modules as the goal independent analyzer except for the module which inputs the program to the analyzer. Here (in both cases) we prepare the analyser to focus on program points as specified in the module (in the second interpreter we ignore those points).
Here are a few examples of running the interpreters:
notice that the recursive calls to collatz, at program point (3,5) are always of the form collatz(even).