diff options
author | Stephane Glondu <steph@glondu.net> | 2010-11-29 23:30:48 +0100 |
---|---|---|
committer | Stephane Glondu <steph@glondu.net> | 2010-11-29 23:30:48 +0100 |
commit | 1aa8b6f6a876af22f538c869f022bc4ca5986b40 (patch) | |
tree | 037f0286a86b2bcee9bfa08f00112005a71e0e18 /coq.ml |
Imported Upstream version 0.1-r13244upstream/0.1-r13244
Diffstat (limited to 'coq.ml')
-rw-r--r-- | coq.ml | 212 |
1 files changed, 212 insertions, 0 deletions
@@ -0,0 +1,212 @@ +(***************************************************************************) +(* This is part of aac_tactics, it is distributed under the terms of the *) +(* GNU Lesser General Public License version 3 *) +(* (see file LICENSE for more details) *) +(* *) +(* Copyright 2009-2010: Thomas Braibant, Damien Pous. *) +(***************************************************************************) + +(** Interface with Coq *) + +type constr = Term.constr + +open Term +open Names +open Coqlib + + +(* The contrib name is used to locate errors when loading constrs *) +let contrib_name = "aac_tactics" + +(* Getting constrs (primitive Coq terms) from exisiting Coq + libraries. *) +let find_constant contrib dir s = + Libnames.constr_of_global (Coqlib.find_reference contrib dir s) + +let init_constant dir s = find_constant contrib_name dir s + +(* A clause specifying that the [let] should not try to fold anything + in the goal *) +let nowhere = + { Tacexpr.onhyps = Some []; + Tacexpr.concl_occs = Rawterm.no_occurrences_expr + } + + +let mk_letin (name: string) (constr: constr) : constr * Proof_type.tactic = + let name = (Names.id_of_string name) in + let letin = + (Tactics.letin_tac + None + (Name name) + constr + None (* or Some ty *) + nowhere + ) in + mkVar name, letin + +let mk_letin' (name: string) (constr: constr) : constr * Proof_type.tactic + = + constr, Tacticals.tclIDTAC + + + +(** {2 General functions} *) + +type goal_sigma = Proof_type.goal Tacmach.sigma +let goal_update (goal : goal_sigma) evar_map : goal_sigma= + let it = Tacmach.sig_it goal in + Tacmach.re_sig it evar_map + +let resolve_one_typeclass goal ty : constr*goal_sigma= + let env = Tacmach.pf_env goal in + let evar_map = Tacmach.project goal in + let em,c = Typeclasses.resolve_one_typeclass env evar_map ty in + c, (goal_update goal em) + +let nf_evar goal c : Term.constr= + let evar_map = Tacmach.project goal in + Evarutil.nf_evar evar_map c + +let evar_unit (gl : goal_sigma) (rlt : constr * constr) : constr * goal_sigma = + let env = Tacmach.pf_env gl in + let evar_map = Tacmach.project gl in + let (em,x) = Evarutil.new_evar evar_map env (fst rlt) in + x,(goal_update gl em) + +let evar_binary (gl: goal_sigma) (rlt: constr * constr) = + let env = Tacmach.pf_env gl in + let evar_map = Tacmach.project gl in + let x = fst rlt in + let ty = mkArrow x (mkArrow x x) in + let (em,x) = Evarutil.new_evar evar_map env ty in + x,( goal_update gl em) + +(* decomp_term : constr -> (constr, types) kind_of_term *) +let decomp_term c = kind_of_term (strip_outer_cast c) + + +(** {2 Bindings with Coq' Standard Library} *) + +module Pair = struct + + let path = ["Coq"; "Init"; "Datatypes"] + let typ = lazy (init_constant path "prod") + let pair = lazy (init_constant path "pair") +end + +module Pos = struct + + let path = ["Coq" ; "NArith"; "BinPos"] + let typ = lazy (init_constant path "positive") + let xI = lazy (init_constant path "xI") + let xO = lazy (init_constant path "xO") + let xH = lazy (init_constant path "xH") + + (* A coq positive from an int *) + let of_int n = + let rec aux n = + begin match n with + | n when n < 1 -> assert false + | 1 -> Lazy.force xH + | n -> mkApp + ( + (if n mod 2 = 0 + then Lazy.force xO + else Lazy.force xI + ), [| aux (n/2)|] + ) + end + in + aux n +end + +module Nat = struct + let path = ["Coq" ; "Init"; "Datatypes"] + let typ = lazy (init_constant path "nat") + let _S = lazy (init_constant path "S") + let _O = lazy (init_constant path "O") + (* A coq nat from an int *) + let of_int n = + let rec aux n = + begin match n with + | n when n < 0 -> assert false + | 0 -> Lazy.force _O + | n -> mkApp + ( + (Lazy.force _S + ), [| aux (n-1)|] + ) + end + in + aux n +end + +(** Lists from the standard library*) +module List = struct + let path = ["Coq"; "Lists"; "List"] + let typ = lazy (init_constant path "list") + let nil = lazy (init_constant path "nil") + let cons = lazy (init_constant path "cons") + let cons ty h t = + mkApp (Lazy.force cons, [| ty; h ; t |]) + let nil ty = + (mkApp (Lazy.force nil, [| ty |])) + let rec of_list ty = function + | [] -> nil ty + | t::q -> cons ty t (of_list ty q) + let type_of_list ty = + mkApp (Lazy.force typ, [|ty|]) +end + +(** Morphisms *) +module Classes = +struct + let classes_path = ["Coq";"Classes"; ] + let morphism = lazy (init_constant (classes_path@["Morphisms"]) "Proper") + + (** build the constr [Proper rel t] *) + let mk_morphism ty rel t = + mkApp (Lazy.force morphism, [| ty; rel; t|]) + + let equivalence = lazy (init_constant (classes_path@ ["RelationClasses"]) "Equivalence") + + (** build the constr [Equivalence ty rel] *) + let mk_equivalence ty rel = + mkApp (Lazy.force equivalence, [| ty; rel|]) +end + +(** a [mset] is a ('a * pos) list *) +let mk_mset ty (l : (constr * int) list) = + let pos = Lazy.force Pos.typ in + let pair_ty = mkApp (Lazy.force Pair.typ , [| ty; pos|]) in + let pair (x : constr) (ar : int) = + mkApp (Lazy.force Pair.pair, [| ty ; pos ; x ; Pos.of_int ar|]) in + let rec aux = function + | [] -> List.nil pair_ty + | (t,ar)::q -> List.cons pair_ty (pair t ar) (aux q) + in + aux l + +(** x r *) +type reltype = Term.constr * Term.constr +(** x r e *) +type eqtype = reltype * Term.constr + + +(** {1 Tacticals} *) + +let tclTIME msg tac = fun gl -> + let u = Sys.time () in + let r = tac gl in + let _ = Pp.msgnl (Pp.str (Printf.sprintf "%s:%fs" msg (Sys.time ()-. u))) in + r + +let tclDEBUG msg tac = fun gl -> + let _ = Pp.msgnl (Pp.str msg) in + tac gl + +let tclPRINT tac = fun gl -> + let _ = Pp.msgnl (Printer.pr_constr (Tacmach.pf_concl gl)) in + tac gl + |