Dear All,
This was the home work. And the home work is hard.
Jan Burse schrieb:
> Jan Burse schrieb:
> > Home Work: Prove more set theory related stuff, for
> > example Knaster-Tarski, etc..
>
> We are not yet at some interesting proofs. Spent the last
> weeks to ease the command language of the proof verifier.
> Main ideas so far:
>
> Holes: The original code of the so called Mini Isabelle Clone
>
> Implicits: We call the new prototype Mini Agda Clone, since
We pushed our mini isabelle clone so that we have
now a tactic engine in place. This tactic engine is
based on Prolog Definite Clause Grammars (DCG) to
pass around the proof state and on the term_variables/2
built-in to recalculate the proof state.
The use of DCG and term_variables/2 works quite fine.
The proof state is simply the holes in the proof
object which have not yet been specified. And
since in our prototype holes are simply Prolog
variables the built-in term_variables/2 can
recalculate the proof state. And DCG will pass
around this list of Prolog variables.
The primitives for the tactic engine are directly
written in Prolog. The most basic primitives are:
/**
* rule(N):
* Extendes the first open hole in the current incomplete
* proof by the given nominal term.
*/
rule(X, [X|L], R) :-
term_variables([X|L], R).
/**
* prefer(I):
* Moves the I-th open hole in the current imcomplete proof
* to the front.
*/
prefer(N, L, [X|R]) :-
nth1(N, L, X, R).
When these primitives are used inside a DCG they can be
used to build Prolog terms. Here is an example how the
Prolog term n1(n2(l1,l2),l3) can be built in two
different ways:
?- phrase((rule(n1(_,_)), rule(n2(_,_)), rule(l1), rule(l2), rule(l3)),
[X], L).
X = n1(n2(l1,l2),l3),
L = []
?- phrase((rule(n1(_,_)), prefer(2), rule(l3), rule(n2(_,_)), rule(l1),
rule(l2)), [X], L).
X = n1(n2(l1,l2),l3),
L = []
In the Mini Isabelle Clone the DCG and term_variables/2
are used to build proof objects. Here is an example of
a proof of a==>(a==>b)==>b in Gentzen LK:
?- theorem ex(a,b) :: a==>(a==>b)==>b by rule(ifR((_->_))),
rule(ifR((_->_))), rule(ifL(_,(_->_),x3)), rule(x2), rule(x4).
Yes
But there is not much gain by rule//1 and prefer//1. We
only serialize the building of the proof object. Of course
the Mini Isabelle Clone can give feedback in each step,
so that dead ends are early dedected, but to make a proof
is still tedious.
So we introduce an new primitive command for building
proof objects. Namely listing the premisses of the
currently unresolved sequent:
/**
* pick(V):
* Enumerates the variables identifiying the premisses in the
* first open hold in the current incomplete proof.
*/
pick(Y, [X|L], [X|L]) :-
sys_freeze_var(X, K),
sys_convert(K, A, _),
sys_melt_var(A, H),
member(Y, H).
So if the first open hole is linked to the following
sequent in the constraint solver:
x1:A1, .., xn:An |- A
Then pick(X) will enumerate x1, .., xn in X. We can now
use DCG to define tactics. Here is the tactic right//0
which will apply the invertible right introduction rules
from the Gentzen LK calculus repeatedly and also the id
rule from this calculus:
/* right//0 will apply invertible rules and the identity rule
on the right hand side of the actual sequent, repeatedly.
The identity rule is non-deterministic, the other rules
are deterministic. */
step --> rule(ifR((->))), !.
step --> rule(andR(,)), !.
step --> rule(iffR(_)), !.
step --> pick(Y), rule(Y).
steps --> prefer(_), step, steps.
steps --> [].
right --> prefer(_), step, steps.
And then there is the left//1 tactic which
tries to apply a left introduction rule from the
Gentzen LK calculus:
/* left//1 will apply a not necesseraly invertible rules on
the left hand side of the actual sequent, once. The parameter
identifies the formula that should be picked from the
sequent. */
left(Y) --> rule(ifL(,(->_),Y)).
left(Y) --> rule(andL((>>_),Y)).
left(Y) --> rule(iffL((->),Y)).
With these tactics, that do not implement a full theorem
prover, but nevertheless provide some convenience, we
can proof the same theorem as before already much
simpler:
?- theorem ex(a,b) :: a==>(a==>b)==>b by
right, left(x3), right.
Yes
With all this help, we are now almost in the middle of the
Tarski Knaster theorem. We are currently about to proof
that lfp and gfp are fixpoints and minimal resp. maximal.
We use the following definitions in our Mini Isabelle
Clone language:
:- fun lfp(u) :: (u set - > u set) - > u set by
lfp(f) = ∩ {a\(f(a) ⊆ a)}.
:- fun gfp(u) :: (u set - > u set) - > u set by
gfp(f) = ∪ {a\(a ⊆ f(a))}.
The minimality resp. maximinality proof goes already
through. But it turns out that the proof is not
complete, some constraints are not resolved. I have
analyzed the situation. It is that a redex remains
unresolved, resulting from the unification F(a) =
f(a). This unification results when applying
lemma_5_1 respectively lemma_5_2.
We are not yet sure what to do. The Jekejeke Minlog
interpreter does not allow non-determinisc
attribute variable hooks. So some higher order
matching that would do some Prolog enumeration
cannot be used inside the constraint solver. Maybe
do something in the spirit of label/1 from CLP(FD).
Source Code Fixpoint Proof
https://gist.github.com/jburse/0ccd12698bfa24ce5c36
G+ Post Progress in Proving Tarski Knaster
https://plus.google.com/116887476001511997780/posts/31MjagH4cEz