remove_refl p1
| _ -> Cic.Appl (List.map remove_refl args))
| Cic.Appl l -> Cic.Appl (List.map remove_refl l)
+ | Cic.LetIn (name,bo,rest) ->
+ Cic.LetIn (name,remove_refl bo,remove_refl rest)
| _ -> t
in
let rec canonical t =
match t with
+ | Cic.LetIn(name,bo,rest) -> Cic.LetIn(name,canonical bo,canonical rest)
| Cic.Appl (((Cic.Const(uri_sym,ens))::tl) as args)
when LibraryObjects.is_sym_eq_URI uri_sym ->
(match p_of_sym ens tl with
* ctx is a term with an open (Rel 1). (Rel 1) is the empty context
*)
let rec aux uri ty left right ctx_d = function
+ | Cic.LetIn (name,body,rest) ->
+ (* we should go in body *)
+ Cic.LetIn (name,body,aux uri ty left right ctx_d rest)
| Cic.Appl ((Cic.Const(uri_ind,ens))::tl)
when LibraryObjects.is_eq_ind_URI uri_ind ||
LibraryObjects.is_eq_ind_r_URI uri_ind ->
contextualize eq ty l r t
;;
-let build_proof_step subst p1 p2 pos l r pred =
- let p1 = Subst.apply_subst subst p1 in
- let p2 = Subst.apply_subst subst p2 in
- let l = Subst.apply_subst subst l in
- let r = Subst.apply_subst subst r in
- let pred = Subst.apply_subst subst pred in
+let build_proof_step lift subst p1 p2 pos l r pred =
+ let p1 = Subst.apply_subst_lift lift subst p1 in
+ let p2 = Subst.apply_subst_lift lift subst p2 in
+ let l = CicSubstitution.lift lift l in
+ let l = Subst.apply_subst_lift lift subst l in
+ let r = CicSubstitution.lift lift r in
+ let r = Subst.apply_subst_lift lift subst r in
+ let pred = CicSubstitution.lift lift pred in
+ let pred = Subst.apply_subst_lift lift subst pred in
let ty,body =
match pred with
| Cic.Lambda (_,ty,body) -> ty,body
mk_eq_ind (Utils.eq_ind_r_URI ()) ty what pred p1 other p2
;;
-let build_proof_term proof =
- let rec aux = function
- | Exact term -> term
- | Step (subst,(_, id1, (pos,id2), pred)) ->
- let p,_,_ = proof_of_id id1 in
- let p1 = aux p in
- let p,l,r = proof_of_id id2 in
- let p2 = aux p in
- build_proof_step subst p1 p2 pos l r pred
+let parametrize_proof p ty =
+ let parameters = CicUtil.metas_of_term p in (* ?if they are under a lambda? *)
+ let parameters =
+ HExtlib.list_uniq (List.sort Pervasives.compare parameters)
in
- aux proof
+ let what = List.map (fun (i,l) -> Cic.Meta (i,l)) parameters in
+ let with_what, lift_no =
+ List.fold_right (fun _ (acc,n) -> ((Cic.Rel n)::acc),n+1) what ([],1)
+ in
+ let p = CicSubstitution.lift (lift_no-1) p in
+ let p =
+ ProofEngineReduction.replace_lifting
+ ~equality:(=) ~what ~with_what ~where:p
+ in
+ let ty_of_m _ = ty (*function
+ | Cic.Meta (i,_) -> List.assoc i menv
+ | _ -> assert false *)
+ in
+ let args, proof,_ =
+ List.fold_left
+ (fun (instance,p,n) m ->
+ (instance@[m],
+ Cic.Lambda
+ (Cic.Name ("x"^string_of_int n),
+ CicSubstitution.lift (lift_no - n - 1) (ty_of_m m),
+ p),
+ n+1))
+ ([Cic.Rel 1],p,1)
+ what
+ in
+ let instance = match args with | [x] -> x | _ -> Cic.Appl args in
+ proof, instance
;;
let wfo goalproof proof =
((List.map (fun (_,i,_,_) -> string_of_int i) goalproof)))
;;
+(* returns the list of ids that should be factorized *)
+let get_duplicate_step_in_wfo l p =
+ let ol = List.rev l in
+ let h = Hashtbl.create 13 in
+ let add i n =
+ let p,_,_ = proof_of_id i in
+ match p with
+ | Exact _ -> ()
+ | _ ->
+ try let (pos,no) = Hashtbl.find h i in Hashtbl.replace h i (pos,no+1)
+ with Not_found -> Hashtbl.add h i (n,1)
+ in
+ let rec aux n = function
+ | Exact _ -> n
+ | Step (_,(_,i1,(_,i2),_)) ->
+ add i1 n;add i2 n;
+ max (aux (n+1) (let p,_,_ = proof_of_id i1 in p))
+ (aux (n+1) (let p,_,_ = proof_of_id i2 in p))
+ in
+ let i = aux 0 p in
+ let _ =
+ List.fold_left
+ (fun acc (_,id,_,_) -> aux acc (let p,_,_ = proof_of_id id in p))
+ i ol
+ in
+ (* now h is complete *)
+ let proofs = Hashtbl.fold (fun k (pos,count) acc->(k,pos,count)::acc) h [] in
+ let proofs = List.filter (fun (_,_,c) -> c > 1) proofs in
+ let proofs =
+ List.sort (fun (_,c1,_) (_,c2,_) -> Pervasives.compare c2 c1) proofs
+ in
+ List.map (fun (i,_,_) -> i) proofs
+;;
+
+let build_proof_term h lift proof =
+ let proof_of_id aux id =
+ let p,l,r = proof_of_id id in
+ try List.assoc id h,l,r with Not_found -> aux p, l, r
+ in
+ let rec aux = function
+ | Exact term -> CicSubstitution.lift lift term
+ | Step (subst,(_, id1, (pos,id2), pred)) ->
+ if Subst.is_in_subst 9 subst then
+ prerr_endline (Printf.sprintf "ID %d-%d has: %s\n" id1 id2 (Subst.ppsubst
+ subst));
+ let p1,_,_ = proof_of_id aux id1 in
+ let p2,l,r = proof_of_id aux id2 in
+ build_proof_step lift subst p1 p2 pos l r pred
+ in
+ aux proof
+;;
+
let build_goal_proof l initial ty se =
let se = List.map (fun i -> Cic.Meta (i,[])) se in
+ let lets = get_duplicate_step_in_wfo l initial in
+ let letsno = List.length lets in
+ let _,mty,_,_ = open_eq ty in
+ let lift_list l = List.map (fun (i,t) -> i,CicSubstitution.lift 1 t) l
+ in
+ let lets,_,h =
+ List.fold_left
+ (fun (acc,n,h) id ->
+ let p,_,_ = proof_of_id id in
+ let cic = build_proof_term h n p in
+ let real_cic,instance =
+ parametrize_proof cic (CicSubstitution.lift n mty)
+ in
+ let h = (id, instance)::lift_list h in
+ acc@[id,real_cic],n+1,h)
+ ([],0,[]) lets
+ in
let proof,se =
let rec aux se current_proof = function
| [] -> current_proof,se
| (pos,id,subst,pred)::tl ->
let p,l,r = proof_of_id id in
- let p = build_proof_term p in
+ let p = build_proof_term h letsno p in
let pos = if pos = Utils.Left then Utils.Right else Utils.Left in
- let proof = build_proof_step subst current_proof p pos l r pred in
+ let proof =
+ build_proof_step letsno subst current_proof p pos l r pred
+ in
let proof,se = aux se proof tl in
- Subst.apply_subst subst proof,
- List.map (fun x -> Subst.apply_subst subst x) se
+ Subst.apply_subst_lift letsno subst proof,
+ List.map (fun x -> Subst.apply_subst_lift letsno subst x) se
in
- aux se initial l
+ aux se (build_proof_term h letsno initial) l
+ in
+ let n,proof =
+ let initial = proof in
+ List.fold_right
+ (fun (id,cic) (n,p) ->
+ n-1,
+ Cic.LetIn (
+ Cic.Name ("H"^string_of_int id),
+ cic, p))
+ lets (letsno-1,initial)
in
- canonical (contextualize_rewrites proof ty), se
+ canonical (contextualize_rewrites proof (CicSubstitution.lift letsno ty)), se
;;
let refl_proof ty term =
;;
let metas_of_proof p =
- let p = build_proof_term p in
+ let p = build_proof_term [] 0 p in
Utils.metas_of_term p
;;
let fix_metas newmeta eq =
let w, p, (ty, left, right, o), menv,_ = open_equality eq in
- (* debug
- let _ , eq =
- fix_metas_old newmeta (w, p, (ty, left, right, o), menv, args) in
- prerr_endline (string_of_equality eq); *)
let subst, metasenv, newmeta = relocate newmeta menv in
let ty = Subst.apply_subst subst ty in
let left = Subst.apply_subst subst left in
in
let p = fix_proof p in
let eq = mk_equality (w, p, (ty, left, right, o), metasenv) in
- (* debug prerr_endline (string_of_equality eq); *)
newmeta+1, eq
exception NotMetaConvertible;;