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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
|
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
(* $Id: proof_trees.ml,v 1.53.2.1 2004/07/16 19:30:49 herbelin Exp $ *)
open Closure
open Util
open Names
open Nameops
open Term
open Termops
open Sign
open Evd
open Environ
open Evarutil
open Proof_type
open Tacred
open Typing
open Libnames
open Nametab
(*
let is_bind = function
| Tacexpr.Cbindings _ -> true
| _ -> false
*)
(* Functions on goals *)
let mk_goal hyps cl =
{ evar_hyps = hyps; evar_concl = cl;
evar_body = Evar_empty}
(* 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.ref with
| Some (Tactic (_,pf), _) -> pf
| _ -> failwith "subproof_of_proof"
let status_of_proof pf = pf.open_subgoals
let is_complete_proof pf = pf.open_subgoals = 0
let is_leaf_proof pf = (pf.ref = None)
let is_tactic_proof pf = match pf.ref with
| Some (Tactic _, _) -> true
| _ -> false
(*******************************************************************)
(* Constraints for existential variables *)
(*******************************************************************)
(* A readable constraint is a global constraint plus a focus set
of existential variables and a signature. *)
(* Functions on readable constraints *)
let mt_evcty gc =
{ it = empty_named_context; sigma = gc }
let rc_of_gc evds gl =
{ it = gl.evar_hyps; sigma = evds }
let rc_add evc (k,v) =
{ it = evc.it;
sigma = Evd.add evc.sigma k v }
let get_hyps evc = evc.it
let get_env evc = Global.env_of_context evc.it
let get_gc evc = evc.sigma
let pf_lookup_name_as_renamed env ccl s =
Detyping.lookup_name_as_renamed env ccl s
let pf_lookup_index_as_renamed env ccl n =
Detyping.lookup_index_as_renamed env ccl n
(*********************************************************************)
(* Pretty printing functions *)
(*********************************************************************)
open Pp
open Printer
(* Il faudrait parametrer toutes les pr_term, term_env, etc. par la
strategie de renommage choisie pour Termast (en particulier, il
faudrait pouvoir etre sur que lookup_as_renamed qui est utilis par
Intros Until fonctionne exactement comme on affiche le but avec
term_env *)
let pf_lookup_name_as_renamed hyps ccl s =
Detyping.lookup_name_as_renamed hyps ccl s
let pf_lookup_index_as_renamed ccl n =
Detyping.lookup_index_as_renamed ccl n
let pr_idl idl = prlist_with_sep pr_spc pr_id idl
let pr_goal g =
let env = evar_env g in
let penv = pr_context_of env in
let pc = prterm_env_at_top env g.evar_concl in
str" " ++ hv 0 (penv ++ fnl () ++
str (emacs_str (String.make 1 (Char.chr 253))) ++
str "============================" ++ fnl () ++
str" " ++ pc) ++ fnl ()
let pr_concl n g =
let env = evar_env g in
let pc = prterm_env_at_top env g.evar_concl in
str (emacs_str (String.make 1 (Char.chr 253))) ++
str "subgoal " ++ int n ++ str " is:" ++ cut () ++ str" " ++ pc
(* print the subgoals but write Subtree proved! even in case some existential
variables remain unsolved, pr_subgoals_existential is a safer version
of pr_subgoals *)
let pr_subgoals = function
| [] -> (str"Proof completed." ++ fnl ())
| [g] ->
let pg = pr_goal g in v 0 (str ("1 "^"subgoal") ++cut () ++ pg)
| g1::rest ->
let rec pr_rec n = function
| [] -> (mt ())
| g::rest ->
let pg = pr_concl n g in
let prest = pr_rec (n+1) rest in
(cut () ++ pg ++ prest)
in
let pg1 = pr_goal g1 in
let pgr = pr_rec 2 rest in
v 0 (int(List.length rest+1) ++ str" subgoals" ++ cut () ++ pg1 ++ pgr)
let pr_subgoal n =
let rec prrec p = function
| [] -> error "No such goal"
| g::rest ->
if p = 1 then
let pg = pr_goal g in
v 0 (str "subgoal " ++ int n ++ str " is:" ++ cut () ++ pg)
else
prrec (p-1) rest
in
prrec n
let pr_seq evd =
let env = evar_env evd
and cl = evd.evar_concl
in
let pdcl = pr_named_context_of env in
let pcl = prterm_env_at_top env cl in
hov 0 (pdcl ++ spc () ++ hov 0 (str"|- " ++ pcl))
let prgl gl =
let pgl = pr_seq gl in
(str"[" ++ pgl ++ str"]" ++ spc ())
let pr_evgl gl =
let phyps = pr_idl (List.rev (ids_of_named_context gl.evar_hyps)) in
let pc = prterm gl.evar_concl in
hov 0 (str"[" ++ phyps ++ spc () ++ str"|- " ++ pc ++ str"]")
let pr_evgl_sign gl =
let ps = pr_named_context_of (evar_env gl) in
let pc = prterm gl.evar_concl in
hov 0 (str"[" ++ ps ++ spc () ++ str"|- " ++ pc ++ str"]")
(* evd.evgoal.lc seems to be printed twice *)
let pr_decl evd =
let pevgl = pr_evgl evd in
let pb =
match evd.evar_body with
| Evar_empty -> (fnl ())
| Evar_defined c -> let pc = prterm c in (str" => " ++ pc ++ fnl ())
in
h 0 (pevgl ++ pb)
let pr_evd evd =
prlist_with_sep pr_fnl
(fun (ev,evd) ->
let pe = pr_decl evd in
h 0 (str (string_of_existential ev) ++ str"==" ++ pe))
(Evd.to_list evd)
let pr_decls decls = pr_evd decls
let pr_evc evc =
let pe = pr_evd evc.sigma in
(pe)
let pr_evars =
prlist_with_sep pr_fnl
(fun (ev,evd) ->
let pegl = pr_evgl_sign evd in
(str (string_of_existential ev) ++ str " : " ++ pegl))
(* Print an enumerated list of existential variables *)
let rec pr_evars_int i = function
| [] -> (mt ())
| (ev,evd)::rest ->
let pegl = pr_evgl_sign evd in
let pei = pr_evars_int (i+1) rest in
(hov 0 (str "Existential " ++ int i ++ str " =" ++ spc () ++
str (string_of_existential ev) ++ str " : " ++ pegl)) ++
fnl () ++ pei
(* Equivalent to pr_subgoals but start from the prooftree and
check for uninstantiated existential variables *)
let pr_subgoals_existential sigma = function
| [] ->
let exl = Evd.non_instantiated sigma in
if exl = [] then
(str"Proof completed." ++ fnl ())
else
let pei = pr_evars_int 1 exl in
(str "No more subgoals but non-instantiated existential " ++
str "variables :" ++fnl () ++ (hov 0 pei))
| [g] ->
let pg = pr_goal g in
v 0 (str ("1 "^"subgoal") ++cut () ++ pg)
| g1::rest ->
let rec pr_rec n = function
| [] -> (mt ())
| g::rest ->
let pc = pr_concl n g in
let prest = pr_rec (n+1) rest in
(cut () ++ pc ++ prest)
in
let pg1 = pr_goal g1 in
let prest = pr_rec 2 rest in
v 0 (int(List.length rest+1) ++ str" subgoals" ++ cut ()
++ pg1 ++ prest ++ fnl ())
|