aboutsummaryrefslogtreecommitdiff
path: root/proofs/tmp-src
blob: eca0119b1852b78c82bb62eca0d3a40d0035497f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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))