package coq-core
The Coq Proof Assistant -- Core Binaries and Tools
Install
Dune Dependency
Authors
Maintainers
Sources
coq-8.20.0.tar.gz
md5=66e57ea55275903bef74d5bf36fbe0f1
sha512=1a7eac6e2f58724a3f9d68bbb321e4cfe963ba1a5551b9b011db4b3f559c79be433d810ff262593d753770ee41ea68fbd6a60daa1e2319ea00dff64c8851d70b
doc/src/firstorder_plugin/formula.ml.html
Source file formula.ml
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 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * Copyright INRIA, CNRS and contributors *) (* <O___,, * (see version control and CREDITS file for authors & dates) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) open Hipattern open Names open Constr open EConstr open Vars open Util open Declarations module RelDecl = Context.Rel.Declaration type flags = { qflag : bool; reds : RedFlags.reds; } let (=?) f g i1 i2 j1 j2= let c=f i1 i2 in if Int.equal c 0 then g j1 j2 else c let (==?) fg h i1 i2 j1 j2 k1 k2= let c=fg i1 i2 j1 j2 in if Int.equal c 0 then h k1 k2 else c type ('a,'b) sum = Left of 'a | Right of 'b type counter = bool -> metavariable module Env : sig type t type uid val empty : t val add : flags -> Environ.env -> Evd.evar_map -> EConstr.t -> t -> t * uid val find : uid -> t -> EConstr.t val repr : uid -> int val hole : uid end = struct module CM = Map.Make(Constr) type t = { max_uid : int; repr : int CM.t; data : Constr.t Int.Map.t; } type uid = int let empty = { max_uid = 1; (* uid 0 is reserved for Meta 1 *) repr = CM.singleton (Constr.mkMeta 1) 0; data = Int.Map.singleton 0 (Constr.mkMeta 1); } let hole = 0 (* This is nonsense, but backwards compatibility mandates it *) let add flags env sigma c e = let c = Reductionops.clos_norm_flags flags.reds env sigma c in let c = EConstr.to_constr ~abort_on_undefined_evars:false sigma c in match CM.find_opt c e.repr with | Some i -> e, i | None -> let i = e.max_uid in let e = { max_uid = i + 1; repr = CM.add c i e.repr; data = Int.Map.add i c e.data; } in e, i let find id e = EConstr.of_constr (Int.Map.find id e.data) let repr id = id end type atom = { atom : Env.uid } let repr_atom state a = Env.find a.atom state let compare_atom a1 a2 = Int.compare (Env.repr a1.atom) (Env.repr a2.atom) let meta_succ m = m+1 let rec nb_prod_after n c= match Constr.kind c with | Prod (_,_,b) ->if n>0 then nb_prod_after (n-1) b else 1+(nb_prod_after 0 b) | _ -> 0 let construct_nhyps env ind = let ind = on_snd EInstance.make ind in let nparams = (fst (Global.lookup_inductive (fst ind))).mind_nparams in let constr_types = Inductiveops.arities_of_constructors env ind in let hyp c = nb_prod_after nparams (EConstr.Unsafe.to_constr c) in Array.map hyp constr_types (* indhyps builds the array of arrays of constructor hyps for (ind largs)*) let ind_hyps env sigma nevar ind largs = let ind = on_snd EInstance.make ind in let types= Inductiveops.arities_of_constructors env ind in let myhyps t = let nparam_decls = Context.Rel.length (fst (Global.lookup_inductive (fst ind))).mind_params_ctxt in let t1=Termops.prod_applist_decls sigma nparam_decls t largs in let t2=snd (decompose_prod_n_decls sigma nevar t1) in fst (decompose_prod_decls sigma t2) in Array.map myhyps types let special_whd ~flags env sigma t = Reductionops.clos_whd_flags flags.reds env sigma t type kind_of_formula= Arrow of constr*constr | False of pinductive*constr list | And of pinductive*constr list*bool | Or of pinductive*constr list*bool | Exists of pinductive*constr list | Forall of constr*constr | Atom of EConstr.t let pop t = Vars.lift (-1) t let fresh_atom ~flags state env sigma atm = let st, uid = Env.add flags env sigma atm !state in let () = state := st in { atom = uid } let hole_atom = { atom = Env.hole } let kind_of_formula ~flags env sigma term = let cciterm = special_whd ~flags env sigma term in match match_with_imp_term env sigma cciterm with Some (a,b)-> Arrow (a, pop b) |_-> match match_with_forall_term env sigma cciterm with Some (_,a,b)-> Forall (a, b) |_-> match match_with_nodep_ind env sigma cciterm with Some (i,l,n)-> let ind,u=EConstr.destInd sigma i in let u = EConstr.EInstance.kind sigma u in let (mib,mip) = Global.lookup_inductive ind in let nconstr=Array.length mip.mind_consnames in if Int.equal nconstr 0 then False((ind,u),l) else let has_realargs=(n>0) in let is_trivial= let is_constant n = Int.equal n 0 in Array.exists is_constant mip.mind_consnrealargs in if Inductiveops.mis_is_recursive (ind,mib,mip) || (has_realargs && not is_trivial) then Atom cciterm else if Int.equal nconstr 1 then And((ind,u),l,is_trivial) else Or((ind,u),l,is_trivial) | _ -> match match_with_sigma_type env sigma cciterm with Some (i,l)-> let (ind, u) = EConstr.destInd sigma i in let u = EConstr.EInstance.kind sigma u in Exists((ind, u), l) |_-> Atom cciterm type atoms = {positive:atom list;negative:atom list} type _ side = | Hyp : bool -> [ `Hyp ] side (* true if treated as hint *) | Concl : [ `Goal ] side let no_atoms = (false,{positive=[];negative=[]}) let build_atoms (type a) ~flags state env sigma metagen (side : a side) cciterm = let trivial =ref false and positive=ref [] and negative=ref [] in let rec build_rec subst polarity cciterm= match kind_of_formula ~flags env sigma cciterm with False(_,_)->if not polarity then trivial:=true | Arrow (a,b)-> build_rec subst (not polarity) a; build_rec subst polarity b | And(i,l,b) | Or(i,l,b)-> if b then begin let unsigned= fresh_atom ~flags state env sigma (substnl subst 0 cciterm) in if polarity then positive:= unsigned :: !positive else negative:= unsigned :: !negative end; let v = ind_hyps env sigma 0 i l in let g i _ decl = build_rec subst polarity (lift i (RelDecl.get_type decl)) in let f l = List.fold_left_i g (1-(List.length l)) () l in if polarity && (* we have a constant constructor *) Array.exists (function []->true|_->false) v then trivial:=true; Array.iter f v | Exists(i,l)-> let var=mkMeta (metagen true) in let v =(ind_hyps env sigma 1 i l).(0) in let g i _ decl = build_rec (var::subst) polarity (lift i (RelDecl.get_type decl)) in List.fold_left_i g (2-(List.length l)) () v | Forall(_,b)-> let var=mkMeta (metagen true) in build_rec (var::subst) polarity b | Atom t-> let unsigned = fresh_atom ~flags state env sigma (substnl subst 0 t) in if not (isMeta sigma (repr_atom !state unsigned)) then (* discarding wildcard atoms *) if polarity then positive:= unsigned :: !positive else negative:= unsigned :: !negative in begin match side with Concl -> build_rec [] true cciterm | Hyp false -> build_rec [] false cciterm | Hyp true -> let rels,head=decompose_prod sigma cciterm in let subst=List.rev_map (fun _->mkMeta (metagen true)) rels in build_rec subst false head;trivial:=false (* special for hints *) end; (!trivial, {positive= !positive; negative= !negative}) type right_pattern = Rarrow | Rand | Ror | Rfalse | Rforall | Rexists of metavariable*constr*bool type left_arrow_pattern= LLatom | LLfalse of pinductive*constr list | LLand of pinductive*constr list | LLor of pinductive*constr list | LLforall of constr | LLexists of pinductive*constr list | LLarrow of constr*constr*constr type left_pattern= Lfalse | Land of pinductive | Lor of pinductive | Lforall of metavariable*constr*bool | Lexists of pinductive | LA of atom*left_arrow_pattern type _ identifier = | GoalId : [ `Goal ] identifier | FormulaId : GlobRef.t -> [ `Hyp ] identifier let goal_id = GoalId let formula_id env gr = FormulaId (Environ.QGlobRef.canonize env gr) type _ pattern = | LeftPattern : left_pattern -> [ `Hyp ] pattern | RightPattern : right_pattern -> [ `Goal ] pattern type 'a t = { id : 'a identifier; constr : atom; pat : 'a pattern; atoms : atoms; } type any_formula = AnyFormula : 'a t -> any_formula exception Is_atom of EConstr.t let build_formula (type a) ~flags state env sigma (side : a side) (nam : a identifier) typ metagen : Env.t * (a t, atom) sum = try let state = ref state in let m=meta_succ(metagen false) in let trivial,atoms= if flags.qflag then build_atoms ~flags state env sigma metagen side typ else no_atoms in let pattern : a pattern = match side with Concl -> let pat= match kind_of_formula ~flags env sigma typ with False(_,_) -> Rfalse | Atom a -> raise (Is_atom a) | And(_,_,_) -> Rand | Or(_,_,_) -> Ror | Exists (i,l) -> let d = RelDecl.get_type (List.last (ind_hyps env sigma 0 i l).(0)) in Rexists(m,d,trivial) | Forall (_,a) -> Rforall | Arrow (a,b) -> Rarrow in RightPattern pat | Hyp _ -> let pat= match kind_of_formula ~flags env sigma typ with False(i,_) -> Lfalse | Atom a -> raise (Is_atom a) | And(i,_,b) -> if b then raise (Is_atom typ) else Land i | Or(i,_,b) -> if b then raise (Is_atom typ) else Lor i | Exists (ind,_) -> Lexists ind | Forall (d,_) -> Lforall(m,d,trivial) | Arrow (a,b) -> let nfa = fresh_atom ~flags state env sigma a in LA (nfa, match kind_of_formula ~flags env sigma a with False(i,l)-> LLfalse(i,l) | Atom t-> LLatom | And(i,l,_)-> LLand(i,l) | Or(i,l,_)-> LLor(i,l) | Arrow(a,c)-> LLarrow(a,c,b) | Exists(i,l)->LLexists(i,l) | Forall(_,_)->LLforall a) in LeftPattern pat in let typ = fresh_atom ~flags state env sigma typ in !state, Left { id = nam; constr = typ; pat = pattern; atoms = atoms} with Is_atom a -> let state = ref state in let a = fresh_atom ~flags state env sigma a in !state, Right a (* already in nf *)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>