aboutsummaryrefslogtreecommitdiff
path: root/contrib/cc/cctac.ml4
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cc/cctac.ml4')
-rw-r--r--contrib/cc/cctac.ml4161
1 files changed, 161 insertions, 0 deletions
diff --git a/contrib/cc/cctac.ml4 b/contrib/cc/cctac.ml4
new file mode 100644
index 0000000000..f7a9e723fa
--- /dev/null
+++ b/contrib/cc/cctac.ml4
@@ -0,0 +1,161 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i camlp4deps: "parsing/grammar.cma kernel/names.cmo parsing/ast.cmo parsing/g_tactic.cmo parsing/g_ltac.cmo parsing/g_constr.cmo" i*)
+
+(* $Id$ *)
+
+(* This file is the interface between the c-c algorithm and Coq *)
+
+open Evd
+open Proof_type
+open Names
+open Libnames
+open Nameops
+open Term
+open Tacmach
+open Tactics
+open Tacticals
+open Ccalgo
+open Tacinterp
+open Ccproof
+open Pp
+open Util
+open Format
+
+exception Not_an_eq
+
+let fail()=raise Not_an_eq
+
+let constr_of_string s () =
+ Declare.constr_of_reference (Nametab.locate (qualid_of_string s))
+
+let eq2eqT_theo = constr_of_string "Coq.Logic.Eqdep_dec.eq2eqT"
+let eqT2eq_theo = constr_of_string "Coq.Logic.Eqdep_dec.eqT2eq"
+let congr_theo = constr_of_string "Coq.cc.CC.Congr_nodep"
+let congr_dep_theo = constr_of_string "Coq.cc.CC.Congr_dep"
+
+let fresh_id1=id_of_string "eq1" and fresh_id2=id_of_string "eq2"
+
+let t_make_app=(Array.fold_left (fun s t->Appli (s,t)))
+
+(* decompose member of equality in an applicative format *)
+
+let rec decompose_term t=
+ match kind_of_term t with
+ App (f,args)->let targs=Array.map decompose_term args in
+ (t_make_app (Symb f) targs)
+ | _->(Symb t)
+
+(* decompose equality in members and type *)
+
+let eq_type_of_term term=
+ match kind_of_term term with
+ App (f,args)->
+ (try
+ let ref = Declare.reference_of_constr f in
+ if (ref=Coqlib.glob_eq || ref=Coqlib.glob_eqT) &&
+ (Array.length args)=3
+ then (args.(0),args.(1),args.(2))
+ else fail()
+ with
+ Not_found -> fail ())
+ | _ ->fail ()
+
+(* read an equality *)
+
+let read_eq term=
+ let (_,t1,t2)=eq_type_of_term term in
+ ((decompose_term t1),(decompose_term t2))
+
+(* rebuild a term from applicative format *)
+
+let rec make_term=function
+ Symb s->s
+ | Appli (s1,s2)->make_app [(make_term s2)] s1
+and make_app l=function
+ Symb s->mkApp (s,(Array.of_list l))
+ | Appli (s1,s2)->make_app ((make_term s2)::l) s1
+
+(* store all equalities from the context *)
+
+let rec read_hyps=function
+ []->[]
+ | (id,_,e)::hyps->let q=(read_hyps hyps) in
+ try (id,(read_eq e))::q with Not_an_eq -> q
+
+(* build a problem ( i.e. read the goal as an equality ) *)
+
+let make_prb gl=
+ let concl=gl.evar_concl in
+ let hyps=gl.evar_hyps in
+ (read_hyps hyps),(read_eq concl)
+
+(* apply tac, followed (or not) by aplication of theorem theo *)
+
+let st_wrap theo tac=
+ tclORELSE tac (tclTHEN (apply theo) tac)
+
+(* generate an adhoc tactic following the proof tree *)
+
+let rec proof_tac uf axioms=function
+ Ax id->(fun gl->(st_wrap (eq2eqT_theo ()) (exact_check (mkVar id)) gl))
+ | Refl t->reflexivity
+ | Trans (p1,p2)->let t=(make_term (snd (type_proof uf axioms p1))) in
+ (tclTHENS (transitivity t)
+ [(proof_tac uf axioms p1);(proof_tac uf axioms p2)])
+ | Sym p->tclTHEN symmetry (proof_tac uf axioms p)
+ | Congr (p1,p2)->
+ (fun gl->
+ let (s1,t1)=(type_proof uf axioms p1) and
+ (s2,t2)=(type_proof uf axioms p2) in
+ let ts1=(make_term s1) and tt1=(make_term t1)
+ and ts2=(make_term s2) and tt2=(make_term t2) in
+ let typ1=pf_type_of gl ts1 and typ2=pf_type_of gl ts2 in
+ let (typb,_,_)=(eq_type_of_term gl.it.evar_concl) in
+ let act=mkApp ((congr_theo ()),[|typ2;typb;ts1;tt1;ts2;tt2|]) in
+ tclORELSE
+ (tclTHENS
+ (apply act)
+ [(proof_tac uf axioms p1);(proof_tac uf axioms p2)])
+ (tclTHEN
+ (let p=mkLambda(destProd typ1) in
+ let acdt=mkApp((congr_dep_theo ()),[|typ2;p;ts1;tt1;ts2|]) in
+ apply acdt) (proof_tac uf axioms p1))
+ gl)
+
+(* wrap everything *)
+
+let cc_tactic gl_sg=
+ Library.check_required_library ["Coq";"cc";"CC"];
+ let gl=gl_sg.it in
+ let prb=try make_prb gl with Not_an_eq ->
+ errorlabstrm "CC" [< str "Couldn't match goal with an equality" >] in
+ match (cc_proof prb) with
+ None->errorlabstrm "CC" [< str "CC couldn't solve goal" >]
+ | Some (p,uf,axioms)->let tac=proof_tac uf axioms p in
+ (tclORELSE (st_wrap (eqT2eq_theo ()) tac)
+ (fun _->errorlabstrm "CC"
+ [< str "CC doesn't know how to handle dependent equality." >]) gl_sg)
+
+(* Tactic registration *)
+
+TACTIC EXTEND CC
+ [ "CC" ] -> [ cc_tactic ]
+END
+
+
+
+
+
+
+
+
+
+
+