>) by ["A"]; take <<|a|>>; so conclude <
> by ["C"];
qed];;
(* ------------------------------------------------------------------------- *)
(* Alternative formulation with lemma construct. *)
(* ------------------------------------------------------------------------- *)
let lemma (s,p) (Goals((asl,w)::gls,jfn) as gl) =
Goals((asl,p)::((s,p)::asl,w)::gls,
fun (thp::thw::oths) ->
jfn(imp_unduplicate(imp_trans thp (shunt thw)) :: oths)) in
prove
<<(exists x. p(x)) ==> (forall x. p(x) ==> p(f(x)))
==> exists y. p(f(f(f(f(y)))))>>
[assume ["A",< >) by ["A"];
take <<|a|>>;
so conclude < > by ["C"];
qed];;
(* ------------------------------------------------------------------------- *)
(* Running a series of proof steps one by one on goals. *)
(* ------------------------------------------------------------------------- *)
let run prf g = itlist (fun f -> f) (rev prf) g;;
(* ------------------------------------------------------------------------- *)
(* LCF-style interactivity. *)
(* ------------------------------------------------------------------------- *)
let current_goal = ref[set_goal False];;
let g x = current_goal := [set_goal x]; hd(!current_goal);;
let e t = current_goal := (t(hd(!current_goal))::(!current_goal));
hd(!current_goal);;
let es t = current_goal := (run t (hd(!current_goal))::(!current_goal));
hd(!current_goal);;
let b() = current_goal := tl(!current_goal); hd(!current_goal);;
(* ------------------------------------------------------------------------- *)
(* Examples. *)
(* ------------------------------------------------------------------------- *)
prove < (forall x. p(x) ==> p(f(x)))
==> exists y. p(y) /\ p(f(y))>>
[our thesis at once;
qed];;
prove
<<(exists x. p(x)) ==> (forall x. p(x) ==> p(f(x)))
==> exists y. p(f(f(f(f(y)))))>>
[assume ["A",< >) by ["A"];
take <<|a|>>;
so our thesis by ["C"];
qed];;
prove < >];
assume ["B",< > by ["A"];
note ("C",< p(f(c))>>) by ["B"];
so our thesis by ["C"; "A"];
qed];;
prove < (forall x. p(x) ==> p(f(x)))
==> exists y. p(y) /\ p(f(y))>>
[assume ["A",< >];
assume ["B",< > by ["A"];
our thesis by ["A"; "B"];
qed];;
prove < >];
assume ["B",< > by ["A"];
note ("C",< p(f(c))>>) by ["B"];
our thesis by ["C"; "A"];
qed];;
prove < >];
assume ["B",< >) by ["A"];
note ("C",< p(f(c))>>) by ["B"];
our thesis by ["C"; "A"; "D"];
qed];;
prove <<(p(a) \/ p(b)) ==> q ==> exists y. p(y)>>
[assume ["A",< >];
assume ["",< > by ["A"];
take <<|a|>>;
so our thesis at once;
qed;
take <<|b|>>;
so our thesis at once;
qed];;
prove
<<(p(a) \/ p(b)) /\ (forall x. p(x) ==> p(f(x))) ==> exists y. p(f(y))>>
[assume ["base",< >;
"Step",< > by ["base"];
so note("A",< >) at once;
note ("X",< p(f(a))>>) by ["Step"];
take <<|a|>>;
our thesis by ["A"; "X"];
qed;
take <<|b|>>;
so our thesis by ["Step"];
qed];;
prove
<<(exists x. p(x)) ==> (forall x. p(x) ==> p(f(x))) ==> exists y. p(f(y))>>
[assume ["A",< >) by ["A"];
so note ("concl",< >) by ["B"];
take <<|a|>>;
our thesis by ["concl"];
qed];;
prove <<(forall x. p(x) ==> q(x)) ==> (forall x. q(x) ==> p(x))
==> (p(a) <=> q(a))>>
[assume ["A",< q(a)>>) by ["A"];
note ("bis",< >);
note ("X",< p(f(a))>>) by ["Step"];
take <<|a|>>;
our thesis by ["base"; "X"];
qed;
suppose ("base",< >);
our thesis by ["Step"; "base"];
qed;
endcase];;
*****)
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* Some amusing efficiency tests versus a "direct" spec. *)
(* ------------------------------------------------------------------------- *)
(*****
let test n = gen "x"
let double_th th =
let tm = concl th in modusponens (modusponens (and_pair tm tm) th) th;;
let testcase n =
gen "x" (funpow n double_th (lcftaut < q(1) \/ p(x)>>));;
let test n = time (spec <<|2|>>) (testcase n),
time (subst ("x" |=> <<|2|>>)) (concl(testcase n));
();;
test 10;;
test 11;;
test 12;;
test 13;;
test 14;;
test 15;;
****)
>];
cases <
p(a)>>) by ["B"];
our thesis by ["von"; "bis"];
qed];;
(*** Mizar-like
prove
<<(p(a) \/ p(b)) /\ (forall x. p(x) ==> p(f(x))) ==> exists y. p(f(y))>>
[assume ["A",<