aboutsummaryrefslogtreecommitdiff
path: root/proofs
diff options
context:
space:
mode:
Diffstat (limited to 'proofs')
-rw-r--r--proofs/evd.ml68
-rw-r--r--proofs/evd.mli48
-rw-r--r--proofs/proof_trees.ml235
-rw-r--r--proofs/proof_trees.mli85
-rw-r--r--proofs/tmp-src148
5 files changed, 556 insertions, 28 deletions
diff --git a/proofs/evd.ml b/proofs/evd.ml
new file mode 100644
index 0000000000..48b2a4b577
--- /dev/null
+++ b/proofs/evd.ml
@@ -0,0 +1,68 @@
+
+(* $Id$ *)
+
+open Util
+open Names
+open Term
+open Sign
+
+(* The type of mappings for existential variables *)
+
+type evar_body =
+ | Evar_empty
+ | Evar_defined of constr
+
+type 'a evar_info = {
+ evar_concl : typed_type; (* the type of the evar ... *)
+ evar_hyps : typed_type signature; (* ... under a certain signature *)
+ evar_body : evar_body; (* its definition *)
+ evar_info : 'a option } (* any other necessary information *)
+
+type 'a evar_map = 'a evar_info Spmap.t
+
+let mt_evd = Spmap.empty
+
+let toList evc = Spmap.fold (fun sp x acc -> (sp,x)::acc) evc []
+let dom evc = Spmap.fold (fun sp _ acc -> sp::acc) evc []
+let map evc k = Spmap.find k evc
+let rmv evc k = Spmap.remove k evc
+let remap evc k i = Spmap.add k i evc
+let in_dom evc k = Spmap.mem k evc
+
+let add_with_info evd sp newinfo =
+ Spmap.add sp newinfo evd
+
+let add_noinfo evd sp sign typ =
+ let newinfo =
+ { evar_concl = typ;
+ evar_hyps = sign;
+ evar_body = Evar_empty;
+ evar_info = None}
+ in
+ Spmap.add sp newinfo evd
+
+let define evd sp body =
+ let oldinfo = map evd sp in
+ let newinfo =
+ { evar_concl = oldinfo.evar_concl;
+ evar_hyps = oldinfo.evar_hyps;
+ evar_body = Evar_defined body;
+ evar_info = oldinfo.evar_info}
+ in
+ match oldinfo.evar_body with
+ | Evar_empty -> Spmap.add sp newinfo evd
+ | _ -> anomaly "cannot define an isevar twice"
+
+(* The list of non-instantiated existential declarations *)
+
+let non_instantiated sigma =
+ let listsp = toList sigma in
+ List.fold_left
+ (fun l ((sp,evd) as d) ->
+ if evd.evar_body = Evar_empty then (d::l) else l)
+ [] listsp
+
+let is_evar sigma sp = in_dom sigma sp
+
+let is_defined sigma sp =
+ let info = map sigma sp in not (info.evar_body = Evar_empty)
diff --git a/proofs/evd.mli b/proofs/evd.mli
new file mode 100644
index 0000000000..8063f42b02
--- /dev/null
+++ b/proofs/evd.mli
@@ -0,0 +1,48 @@
+
+(* $Id$ *)
+
+(*i*)
+open Names
+open Term
+open Sign
+(*i*)
+
+(* The type of mappings for existential variables.
+ The keys are section paths and the associated information is a record
+ containing the type of the evar ([concl]), the signature under which
+ it was introduced ([hyps]), its definition ([body]) and any other
+ possible information if necessary ([info]).
+*)
+
+type evar_body =
+ | Evar_empty
+ | Evar_defined of constr
+
+type 'a evar_info = {
+ evar_concl : typed_type;
+ evar_hyps : typed_type signature;
+ evar_body : evar_body;
+ evar_info : 'a option }
+
+type 'a evar_map
+
+val dom : 'a evar_map -> section_path list
+val map : 'a evar_map -> section_path -> 'a evar_info
+val rmv : 'a evar_map -> section_path -> 'a evar_map
+val remap : 'a evar_map -> section_path -> 'a evar_info -> 'a evar_map
+val in_dom : 'a evar_map -> section_path -> bool
+val toList : 'a evar_map -> (section_path * 'a evar_info) list
+
+val mt_evd : 'a evar_map
+val add_with_info : 'a evar_map -> section_path -> 'a evar_info -> 'a evar_map
+val add_noinfo :
+ 'a evar_map -> section_path -> typed_type signature -> typed_type
+ -> 'a evar_map
+
+val define : 'a evar_map -> section_path -> constr -> 'a evar_map
+
+val non_instantiated : 'a evar_map -> (section_path * 'a evar_info) list
+val is_evar : 'a evar_map -> section_path -> bool
+
+val is_defined : 'a evar_map -> section_path -> bool
+
diff --git a/proofs/proof_trees.ml b/proofs/proof_trees.ml
index 77e8314d5f..4680607244 100644
--- a/proofs/proof_trees.ml
+++ b/proofs/proof_trees.ml
@@ -1,7 +1,11 @@
(* $Id$ *)
+open Names
open Term
+open Sign
+open Evd
+open Stamps
type bindOcc =
| Dep of identifier
@@ -11,20 +15,20 @@ type bindOcc =
type 'a substitution = (bindOcc * 'a) list
type tactic_arg =
- | COMMAND of Coqast.t
- | CONSTR of constr
- | IDENTIFIER of identifier
- | INTEGER of int
- | CLAUSE of identifier list
- | BINDINGS of Coqast.t substitution
- | CBINDINGS of constr substitution
- | QUOTED_STRING of string
- | TACEXP of Coqast.t
- | REDEXP of string * Coqast.t list
- | FIXEXP of identifier * int * Coqast.t
- | COFIXEXP of identifier * Coqast.t
- | LETPATTERNS of int list option * (identifier * int list) list
- | INTROPATTERN of intro_pattern
+ | Command of Coqast.t
+ | Constr of constr
+ | Identifier of identifier
+ | Integer of int
+ | Clause of identifier list
+ | Bindings of Coqast.t substitution
+ | Cbindings of constr substitution
+ | Quoted_string of string
+ | Tacexp of Coqast.t
+ | Redexp of string * Coqast.t list
+ | Fixexp of identifier * int * Coqast.t
+ | Cofixexp of identifier * Coqast.t
+ | Letpatterns of int list option * (identifier * int list) list
+ | Intropattern of intro_pattern
and intro_pattern =
| IdPat of identifier
@@ -33,3 +37,206 @@ and intro_pattern =
| ListPat of intro_pattern list
and tactic_expression = string * tactic_arg list
+
+
+type pf_status = Complete_proof | Incomplete_proof
+
+type prim_rule_name =
+ | Intro
+ | Intro_after
+ | Intro_replacing
+ | Fix
+ | Cofix
+ | Refine
+ | Convert_concl
+ | Convert_hyp
+ | Thin
+ | Move of bool
+
+type prim_rule = {
+ name : prim_rule_name;
+ hypspecs : identifier list;
+ newids : identifier list;
+ params : Coqast.t list;
+ terms : constr list }
+
+type local_constraints = Spset.t
+
+type proof_tree = {
+ status : pf_status;
+ goal : goal;
+ ref : (rule * proof_tree list) option;
+ subproof : proof_tree option }
+
+and goal = ctxtty evar_info
+
+and rule =
+ | Prim of prim_rule
+ | Tactic of tactic_expression
+ | Context of ctxtty
+ | Local_constraints of local_constraints
+
+and ctxtty = {
+ pgm : constr option;
+ mimick : proof_tree option;
+ lc : local_constraints }
+
+and evar_declarations = ctxtty evar_map
+
+let is_bind = function
+ | Bindings _ -> true
+ | _ -> false
+
+let lc_toList lc = Spset.elements lc
+
+(* Functions on goals *)
+
+let mkGOAL ctxt sign cl =
+ { evar_hyps = sign;
+ evar_concl = cl;
+ evar_body = Evar_empty;
+ evar_info = Some ctxt }
+
+(* Functions on the information associated with existential variables *)
+
+let mt_ctxt lc = { pgm = None; mimick = None; lc = lc }
+
+let get_ctxt ctxt =
+ match ctxt.evar_info with
+ | Some x -> x
+ | None -> assert false
+
+let get_pgm evd =
+ match evd.evar_info with
+ | Some x -> x.pgm
+ | None -> assert false
+
+let set_pgm pgm ctxt = { ctxt with pgm = pgm }
+
+let get_mimick evd =
+ match evd.evar_info with
+ | Some x -> x.mimick
+ | None -> assert false
+
+let set_mimick mimick ctxt = {mimick = mimick; pgm = ctxt.pgm;lc=ctxt.lc}
+
+let get_lc evd =
+ match evd.evar_info with
+ | Some x -> x.lc
+ | None -> assert false
+
+(* Functions on proof trees *)
+
+let ref_of_proof pf =
+ match pf.ref with
+ | None -> failwith "rule_of_proof"
+ | Some r -> r
+
+let rule_of_proof pf =
+ let (r,_) = ref_of_proof pf in r
+
+let children_of_proof pf =
+ let (_,cl) = ref_of_proof pf in cl
+
+let goal_of_proof pf = pf.goal
+
+let subproof_of_proof pf =
+ match pf.subproof with
+ | None -> failwith "subproof_of_proof"
+ | Some pf -> pf
+
+let status_of_proof pf = pf.status
+
+let is_complete_proof pf = pf.status = Complete_proof
+
+let is_leaf_proof pf =
+ match pf.ref with
+ | None -> true
+ | Some _ -> false
+
+let is_tactic_proof pf =
+ match pf.subproof with
+ | Some _ -> true
+ | None -> false
+
+
+(*******************************************************************)
+(* Constraints for existential variables *)
+(*******************************************************************)
+
+(* A local constraint is just a set of section_paths *)
+
+(* recall : type local_constraints = Spset.t *)
+
+(* A global constraint is a mappings of existential variables
+ with some extra information for the program and mimick
+ tactics. *)
+
+type global_constraints = evar_declarations timestamped
+
+(* A readable constraint is a global constraint plus a focus set
+ of existential variables and a signature. *)
+
+type evar_recordty = {
+ focus : local_constraints;
+ sign : typed_type signature;
+ decls : evar_declarations }
+
+and readable_constraints = evar_recordty timestamped
+
+(* Functions on readable constraints *)
+
+let mt_evcty lc gc =
+ ts_mk { focus = lc; sign = nil_sign; decls = gc }
+
+let evc_of_evds evds gl =
+ ts_mk { focus = (get_lc gl); sign = gl.evar_hyps ; decls = evds }
+
+let rc_of_gc gc gl = evc_of_evds (ts_it gc) gl
+
+let rc_add evc (k,v) =
+ ts_mod
+ (fun evc -> { focus =(Spset.add k evc.focus);
+ sign = evc.sign;
+ decls = Evd.add_with_info evc.decls k v })
+ evc
+
+let get_hyps evc = (ts_it evc).sign
+let get_focus evc = (ts_it evc).focus
+let get_decls evc = (ts_it evc).decls
+let get_gc evc = (ts_mk (ts_it evc).decls)
+let remap evc (k,v) =
+ ts_mod
+ (fun evc -> { focus = evc.focus;
+ sign = evc.sign;
+ decls = Evd.remap evc.decls k v })
+ evc
+
+let lc_exists f lc = Spset.fold (fun e b -> (f e) or b) lc false
+
+(* MENTIONS SIGMA SP LOC is true exactly when LOC is defined, and SP is
+ * on LOC's access list, or an evar on LOC's access list mentions SP. *)
+
+let rec mentions sigma sp loc =
+ let loc_evd = map (ts_it sigma).decls loc in
+ match loc_evd.evar_body with
+ | Evar_defined _ -> (Spset.mem sp (get_lc loc_evd)
+ or lc_exists (mentions sigma sp) (get_lc loc_evd))
+ | _ -> false
+
+(* ACCESSIBLE SIGMA SP LOC is true exactly when SP is on LOC's access list,
+ * or there exists a LOC' on LOC's access list such that
+ * MENTIONS SIGMA SP LOC' is true. *)
+
+let rec accessible sigma sp loc =
+ let loc_evd = map (ts_it sigma).decls loc in
+ lc_exists (fun loc' -> sp = loc' or mentions sigma sp loc') (get_lc loc_evd)
+
+
+(* [ctxt_access sigma sp] is true when SIGMA is accessing a current
+ * accessibility list ACCL, and SP is either on ACCL, or is mentioned
+ * in the body of one of the ACCL. *)
+
+let ctxt_access sigma sp =
+ lc_exists (fun sp' -> sp' = sp or mentions sigma sp sp') (ts_it sigma).focus
+
diff --git a/proofs/proof_trees.mli b/proofs/proof_trees.mli
index 99d94d01e3..38f7aeb8ec 100644
--- a/proofs/proof_trees.mli
+++ b/proofs/proof_trees.mli
@@ -4,8 +4,12 @@
(*i*)
open Names
open Term
+open Evd
(*i*)
+(* This module declares the structure of proof trees, global and
+ readable constraints, and a few utilities on these types *)
+
type bindOcc =
| Dep of identifier
| NoDep of int
@@ -14,20 +18,20 @@ type bindOcc =
type 'a substitution = (bindOcc * 'a) list
type tactic_arg =
- | COMMAND of Coqast.t
- | CONSTR of constr
- | IDENTIFIER of identifier
- | INTEGER of int
- | CLAUSE of identifier list
- | BINDINGS of Coqast.t substitution
- | CBINDINGS of constr substitution
- | QUOTED_STRING of string
- | TACEXP of Coqast.t
- | REDEXP of string * Coqast.t list
- | FIXEXP of identifier * int * Coqast.t
- | COFIXEXP of identifier * Coqast.t
- | LETPATTERNS of int list option * (identifier * int list) list
- | INTROPATTERN of intro_pattern
+ | Command of Coqast.t
+ | Constr of constr
+ | Identifier of identifier
+ | Integer of int
+ | Clause of identifier list
+ | Bindings of Coqast.t substitution
+ | Cbindings of constr substitution
+ | Quoted_string of string
+ | Tacexp of Coqast.t
+ | Redexp of string * Coqast.t list
+ | Fixexp of identifier * int * Coqast.t
+ | Cofixexp of identifier * Coqast.t
+ | Letpatterns of int list option * (identifier * int list) list
+ | Intropattern of intro_pattern
and intro_pattern =
| IdPat of identifier
@@ -36,3 +40,56 @@ and intro_pattern =
| ListPat of intro_pattern list
and tactic_expression = string * tactic_arg list
+
+
+type pf_status = Complete_proof | Incomplete_proof
+
+type prim_rule_name =
+ | Intro
+ | Intro_after
+ | Intro_replacing
+ | Fix
+ | Cofix
+ | Refine
+ | Convert_concl
+ | Convert_hyp
+ | Thin
+ | Move of bool
+
+type prim_rule = {
+ name : prim_rule_name;
+ hypspecs : identifier list;
+ newids : identifier list;
+ params : Coqast.t list;
+ terms : constr list }
+
+type local_constraints = Spset.t
+
+(* [ref] = [None] if the goal has still to be proved,
+ and [Some (r,l)] if the rule [r] was applied to the goal
+ and gave [l] as subproofs to be completed.
+
+ [subproof] = [(Some p)] if [ref = (Some(Tactic t,l))];
+ [p] is then the proof that the goal can be proven if the goals
+ in [l] are solved *)
+
+type proof_tree = {
+ status : pf_status;
+ goal : goal;
+ ref : (rule * proof_tree list) option;
+ subproof : proof_tree option }
+
+and goal = ctxtty evar_info
+
+and rule =
+ | Prim of prim_rule
+ | Tactic of tactic_expression
+ | Context of ctxtty
+ | Local_constraints of local_constraints
+
+and ctxtty = {
+ pgm : constr option;
+ mimick : proof_tree option;
+ lc : local_constraints }
+
+and evar_declarations = ctxtty evar_map
diff --git a/proofs/tmp-src b/proofs/tmp-src
new file mode 100644
index 0000000000..eca0119b18
--- /dev/null
+++ b/proofs/tmp-src
@@ -0,0 +1,148 @@
+
+(********* INSTANTIATE ****************************************************)
+
+(* existential_type gives the type of an existential *)
+let existential_type env k =
+ let (sp,args) = destConst k in
+ let evd = Evd.map (evar_map env) sp in
+ instantiate_constr
+ (ids_of_sign evd.evar_hyps) evd.evar_concl.body (Array.to_list args)
+
+(* existential_value gives the value of a defined existential *)
+let existential_value env k =
+ let (sp,args) = destConst k in
+ if defined_const env k then
+ let evd = Evd.map (evar_map env) sp in
+ match evd.evar_body with
+ | EVAR_DEFINED c ->
+ instantiate_constr (ids_of_sign evd.evar_hyps) c (Array.to_list args)
+ | _ -> anomalylabstrm "termenv__existential_value"
+ [< 'sTR"The existential variable code just registered a" ;
+ 'sPC ; 'sTR"grave internal error." >]
+ else
+ failwith "undefined existential"
+
+
+(******* REDUCTION ********************************************************)
+
+(* Expanding existential variables (trad.ml, progmach.ml) *)
+(* 1- whd_ise fails if an existential is undefined *)
+let rec whd_ise env = function
+ | DOPN(Const sp,_) as k ->
+ if Evd.in_dom (evar_map env) sp then
+ if defined_constant env k then
+ whd_ise env (constant_value env k)
+ else
+ errorlabstrm "whd_ise"
+ [< 'sTR"There is an unknown subterm I cannot solve" >]
+ else
+ k
+ | DOP2(Cast,c,_) -> whd_ise env c
+ | DOP0(Sort(Type(_))) -> DOP0(Sort(Type(dummy_univ)))
+ | c -> c
+
+
+(* 2- undefined existentials are left unchanged *)
+let rec whd_ise1 env = function
+ | (DOPN(Const sp,_) as k) ->
+ if Evd.in_dom (evar_map env) sp & defined_const env k then
+ whd_ise1 env (constant_value env k)
+ else
+ k
+ | DOP2(Cast,c,_) -> whd_ise1 env c
+ | DOP0(Sort(Type _)) -> DOP0(Sort(Type dummy_univ))
+ | c -> c
+
+let nf_ise1 env = strong (whd_ise1 env) env
+
+(* Same as whd_ise1, but replaces the remaining ISEVAR by Metavariables
+ * Similarly we have is_fmachine1_metas and is_resolve1_metas *)
+
+let rec whd_ise1_metas env = function
+ | (DOPN(Const sp,_) as k) ->
+ if Evd.in_dom (evar_map env) sp then
+ if defined_const env k then
+ whd_ise1_metas env (const_or_ex_value env k)
+ else
+ let m = DOP0(Meta (new_meta())) in
+ DOP2(Cast,m,const_or_ex_type env k)
+ else
+ k
+ | DOP2(Cast,c,_) -> whd_ise1_metas env c
+ | c -> c
+
+(********************************************************************)
+(* Special-Purpose Reduction *)
+(********************************************************************)
+
+let whd_meta env = function
+ | DOP0(Meta p) as u -> (try List.assoc p (metamap env) with Not_found -> u)
+ | x -> x
+
+(* Try to replace all metas. Does not replace metas in the metas' values
+ * Differs from (strong whd_meta). *)
+let plain_instance env c =
+ let s = metamap env in
+ let rec irec = function
+ | DOP0(Meta p) as u -> (try List.assoc p s with Not_found -> u)
+ | DOP1(oper,c) -> DOP1(oper, irec c)
+ | DOP2(oper,c1,c2) -> DOP2(oper, irec c1, irec c2)
+ | DOPN(oper,cl) -> DOPN(oper, Array.map irec cl)
+ | DOPL(oper,cl) -> DOPL(oper, List.map irec cl)
+ | DLAM(x,c) -> DLAM(x, irec c)
+ | DLAMV(x,v) -> DLAMV(x, Array.map irec v)
+ | u -> u
+ in
+ if s = [] then c else irec c
+
+(* Pourquoi ne fait-on pas nf_betaiota si s=[] ? *)
+let instance env c =
+ let s = metamap env in
+ if s = [] then c else nf_betaiota env (plain_instance env c)
+
+(************ REDUCTION.MLI **********************************************)
+
+(*s Special-Purpose Reduction Functions *)
+val whd_meta : 'a reduction_function
+val plain_instance : 'a reduction_function
+val instance : 'a reduction_function
+
+val whd_ise : 'a reduction_function
+val whd_ise1 : 'a reduction_function
+val nf_ise1 : 'a reduction_function
+val whd_ise1_metas : 'a reduction_function
+
+(*********** TYPEOPS *****************************************************)
+
+(* Existentials. *)
+
+let type_of_existential env c =
+ let (sp,args) = destConst c in
+ let info = Evd.map (evar_map env) sp in
+ let hyps = info.evar_hyps in
+ check_hyps (basename sp) env hyps;
+ instantiate_type (ids_of_sign hyps) info.evar_concl (Array.to_list args)
+
+(* Constants or existentials. *)
+
+let type_of_constant_or_existential env c =
+ if is_existential c then
+ type_of_existential env c
+ else
+ type_of_constant env c
+
+
+(******** TYPING **********************************************************)
+
+ | IsMeta n ->
+ let metaty =
+ try lookup_meta n env
+ with Not_found -> error "A variable remains non instanciated"
+ in
+ (match kind_of_term metaty with
+ | IsCast (typ,kind) ->
+ ({ uj_val = cstr; uj_type = typ; uj_kind = kind }, cst0)
+ | _ ->
+ let (jty,cst) = execute mf env metaty in
+ let k = whd_betadeltaiotaeta env jty.uj_type in
+ ({ uj_val = cstr; uj_type = metaty; uj_kind = k }, cst))