id w (CicPp.ppterm ty)
(CicPp.ppterm left)
(Utils.string_of_comparison o) (CicPp.ppterm right)
- (String.concat ", " (List.map (fun (i,_,_) -> string_of_int i) m))
+ (String.concat ", " (List.map (fun (i,_,_) -> string_of_int i) m))
| Some (_, context, _) ->
let names = Utils.names_of_context context in
let w, _, (ty, left, right, o), m , id = open_equality eq in
id w (CicPp.pp ty names)
(CicPp.pp left names) (Utils.string_of_comparison o)
(CicPp.pp right names)
- (String.concat ", " (List.map (fun (i,_,_) -> string_of_int i) m))
+ (String.concat ", " (List.map (fun (i,_,_) -> string_of_int i) m))
;;
let compare (_,_,_,s1,_,_) (_,_,_,s2,_,_) =
let compose_contexts ctx1 ctx2 =
ProofEngineReduction.replace_lifting
- ~equality:(=) ~what:[Cic.Rel 1] ~with_what:[ctx2] ~where:ctx1
+ ~equality:(=) ~what:[Cic.Implicit(Some `Hole)] ~with_what:[ctx2] ~where:ctx1
;;
let put_in_ctx ctx t =
ProofEngineReduction.replace_lifting
- ~equality:(=) ~what:[Cic.Rel 1] ~with_what:[t] ~where:ctx
+ ~equality:(=) ~what:[Cic.Implicit (Some `Hole)] ~with_what:[t] ~where:ctx
;;
let mk_eq uri ty l r =
;;
let contextualize uri ty left right t =
+ let hole = Cic.Implicit (Some `Hole) in
(* aux [uri] [ty] [left] [right] [ctx] [t]
*
* the parameters validate this invariant
* t: eq(uri) ty left right
* that is used only by the base case
*
- * ctx is a term with an open (Rel 1). (Rel 1) is the empty context
+ * ctx is a term with an hole. Cic.Implicit(Some `Hole) is the empty context
*)
let rec aux uri ty left right ctx_d = function
| Cic.Appl ((Cic.Const(uri_sym,ens))::tl)
let m, ctx_c = if is_not_fixed_lp then rp,lp else lp,rp in
(* they were under a lambda *)
let m = CicSubstitution.subst (Cic.Implicit None) m in
- let ctx_c = CicSubstitution.subst (Cic.Rel 1) ctx_c in
+ let ctx_c = CicSubstitution.subst hole ctx_c in
m, ctx_c
in
(* create the compound context and put the terms under it *)
let uri_ind = LibraryObjects.eq_ind_URI ~eq:uri in
let pred =
(* ctx_d will go under a lambda, but put_in_ctx substitutes Rel 1 *)
- let ctx_d = CicSubstitution.lift_from 2 1 ctx_d in (* bleah *)
- let r = put_in_ctx ctx_d (CicSubstitution.lift 1 left) in
- let l = ctx_d in
+ let r = CicSubstitution.lift 1 (put_in_ctx ctx_d left) in
+ let l =
+ let ctx_d = CicSubstitution.lift 1 ctx_d in
+ put_in_ctx ctx_d (Cic.Rel 1)
+ in
let lty = CicSubstitution.lift 1 ty in
Cic.Lambda (Cic.Name "foo",ty,(mk_eq uri lty l r))
in
mk_sym uri_sym ty d_right d_left
(mk_eq_ind uri_ind ty left pred refl_eq right t)
in
- let empty_context = Cic.Rel 1 in
- aux uri ty left right empty_context t
+ aux uri ty left right hole t
;;
let contextualize_rewrites t ty =
let eq,ty,l,r = open_eq ty in
contextualize eq ty l r t
;;
-
+
+let add_subst subst =
+ function
+ | Exact t -> Exact (Subst.apply_subst subst t)
+ | Step (s,(rule, id1, (pos,id2), pred)) ->
+ Step (Subst.concat subst s,(rule, id1, (pos,id2), pred))
+;;
+
let build_proof_step ?(sym=false) 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
| Exact t ->
Printf.sprintf "%d = %s: %s = %s [%s]" id
(CicPp.pp t names) (CicPp.pp l names) (CicPp.pp r names)
- (String.concat ", " (List.map (fun (i,_,_) -> string_of_int i) m))
+ (String.concat ", " (List.map (fun (i,_,_) -> string_of_int i) m))
| Step (_,(step,id1, (_,id2), _) ) ->
Printf.sprintf "%6d: %s %6d %6d %s = %s [%s]" id
(string_of_rule step)
id1 id2 (CicPp.pp l names) (CicPp.pp r names)
- (String.concat ", " (List.map (fun (i,_,_) -> string_of_int i) m))
+ (String.concat ", " (List.map (fun (i,_,_) -> string_of_int i) m))
with
Not_found -> assert false
"\nand then subsumed by " ^ string_of_int id ^ " when " ^ Subst.ppsubst subst
;;
+module OT =
+ struct
+ type t = int
+ let compare = Pervasives.compare
+ end
+
+module M = Map.Make(OT)
+
+let rec find_deps m i =
+ if M.mem i m then m
+ else
+ let p,_,_ = proof_of_id i in
+ match p with
+ | Exact _ -> M.add i [] m
+ | Step (_,(_,id1,(_,id2),_)) ->
+ let m = find_deps m id1 in
+ let m = find_deps m id2 in
+ M.add i (M.find id1 m @ M.find id2 m @ [id1;id2]) m
+;;
+
+let topological_sort l =
+ (* build the partial order relation *)
+ let m =
+ List.fold_left (fun m i -> find_deps m i)
+ M.empty l
+ in
+ let m = M.map (fun x -> Some x) m in
+ (* utils *)
+ let keys m = M.fold (fun i _ acc -> i::acc) m [] in
+ let split l m = List.filter (fun i -> M.find i m = Some []) l in
+ let purge l m =
+ M.mapi
+ (fun k v -> if List.mem k l then None else
+ match v with
+ | None -> None
+ | Some ll -> Some (List.filter (fun i -> not (List.mem i l)) ll))
+ m
+ in
+ let rec aux m =
+ let keys = keys m in
+ let ok = split keys m in
+ let m = purge ok m in
+ ok @ (if ok = [] then [] else aux m)
+ in
+ aux m
+;;
+
+
(* returns the list of ids that should be factorized *)
let get_duplicate_step_in_wfo l p =
let ol = List.rev l in
(* NOTE: here the n parameter is an approximation of the dependency
between equations. To do things seriously we should maintain a
dependency graph. This approximation is not perfect. *)
- let add i n =
+ let add i =
let p,_,_ = proof_of_id i in
match p with
| Exact _ -> true
| _ ->
try
- let (pos,no) = Hashtbl.find h i in
- Hashtbl.replace h i (pos,no+1);
+ let no = Hashtbl.find h i in
+ Hashtbl.replace h i (no+1);
false
- with Not_found -> Hashtbl.add h i (n,1);true
+ with Not_found -> Hashtbl.add h i 1;true
in
- let rec aux n = function
- | Exact _ -> n
+ let rec aux = function
+ | Exact _ -> ()
| Step (_,(_,i1,(_,i2),_)) ->
- let go_on_1 = add i1 n in
- let go_on_2 = add i2 n in
- max
- (if go_on_1 then aux (n+1) (let p,_,_ = proof_of_id i1 in p) else n+1)
- (if go_on_2 then aux (n+1) (let p,_,_ = proof_of_id i2 in p) else n+1)
- 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
+ let go_on_1 = add i1 in
+ let go_on_2 = add i2 in
+ if go_on_1 then aux (let p,_,_ = proof_of_id i1 in p);
+ if go_on_2 then aux (let p,_,_ = proof_of_id i2 in p)
in
+ aux p;
+ List.iter
+ (fun (_,_,id,_,_) -> aux (let p,_,_ = proof_of_id id in p))
+ ol;
(* 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 proofs = Hashtbl.fold (fun k count acc-> (k,count)::acc) h [] in
+ let proofs = List.filter (fun (_,c) -> c > 1) proofs in
+ topological_sort (List.map (fun (i,_) -> i) proofs)
;;
let build_proof_term h lift proof =
| _ -> assert false
in
let p = build_proof_step lift subst p1 p2 pos l r pred in
-(* let cond = (not (List.mem 302 (Utils.metas_of_term p)) || id1 = 8 || id1 = 132) in
- if not cond then
- prerr_endline ("ERROR " ^ string_of_int id1 ^ " " ^ string_of_int id2);
- assert cond;*)
- p
+(* let cond = (not (List.mem 302 (Utils.metas_of_term p)) || id1 = 8 || id1 = 132) in
+ if not cond then
+ prerr_endline ("ERROR " ^ string_of_int id1 ^ " " ^ string_of_int id2);
+ assert cond;*)
+ p
in
aux proof
;;
cic, p))
lets (letsno-1,initial)
in
- (*canonical (contextualize_rewrites proof (CicSubstitution.lift letsno ty))*)proof, se
+ (proof,se)
+ (* canonical (contextualize_rewrites proof (CicSubstitution.lift letsno ty)),
+ se *)
;;
let refl_proof ty term =
let fix_metas newmeta eq =
let w, p, (ty, left, right, o), menv,_ = open_equality eq in
let to_be_relocated =
+(* List.map (fun i ,_,_ -> i) menv *)
HExtlib.list_uniq
(List.sort Pervasives.compare
- (Utils.metas_of_term left @ Utils.metas_of_term right))
+ (Utils.metas_of_term left @ Utils.metas_of_term right))
in
let subst, metasenv, newmeta = relocate newmeta menv to_be_relocated in
let ty = Subst.apply_subst subst ty in
menv (argsno, t))
;;
+let symmetric eq_ty l id uri m =
+ let eq = Cic.MutInd(uri,0,[]) in
+ let pred =
+ Cic.Lambda (Cic.Name "Sym",eq_ty,
+ Cic.Appl [CicSubstitution.lift 1 eq ;
+ CicSubstitution.lift 1 eq_ty;
+ Cic.Rel 1;CicSubstitution.lift 1 l])
+ in
+ let prefl =
+ Exact (Cic.Appl
+ [Cic.MutConstruct(uri,0,1,[]);eq_ty;l])
+ in
+ let id1 =
+ let eq = mk_equality (0,prefl,(eq_ty,l,l,Utils.Eq),m) in
+ let (_,_,_,_,id) = open_equality eq in
+ id
+ in
+ Step(Subst.empty_subst,
+ (Demodulation,id1,(Utils.Left,id),pred))
+;;
+