X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Focaml%2Ftactics%2FproofEngineHelpers.ml;h=20e8341a6c90d987a401491902a26898f85f7818;hb=ab0954eab207a70e6ad5f2991cc117608deff55b;hp=c1f4ebc3c7ac58466066cbf25e7001802226b756;hpb=abd9e5cfa8e7b6923e0664a4813a0a842f5c4e76;p=helm.git diff --git a/helm/ocaml/tactics/proofEngineHelpers.ml b/helm/ocaml/tactics/proofEngineHelpers.ml index c1f4ebc3c..20e8341a6 100644 --- a/helm/ocaml/tactics/proofEngineHelpers.ml +++ b/helm/ocaml/tactics/proofEngineHelpers.ml @@ -23,6 +23,8 @@ * http://cs.unibo.it/helm/. *) +exception Bad_pattern of string + let new_meta_of_proof ~proof:(_, metasenv, _, _) = CicMkImplicit.new_meta metasenv [] @@ -110,8 +112,8 @@ let compare_metasenvs ~oldmetasenv ~newmetasenv = (** finds the _pointers_ to subterms that are alpha-equivalent to wanted in t *) let find_subterms ~eq ~wanted t = - let rec find wanted t = - if eq wanted t then + let rec find w t = + if eq w t then [t] else match t with @@ -122,31 +124,134 @@ let find_subterms ~eq ~wanted t = fun acc e -> match e with | None -> acc - | Some t -> find wanted t @ acc + | Some t -> find w t @ acc ) [] ctx | Cic.Lambda (_, t1, t2) | Cic.Prod (_, t1, t2) | Cic.LetIn (_, t1, t2) -> - find wanted t1 @ find (CicSubstitution.lift 1 wanted) t2 + find w t1 @ find (CicSubstitution.lift 1 w) t2 | Cic.Appl l -> - List.fold_left (fun acc t -> find wanted t @ acc) [] l - | Cic.Cast (t, ty) -> find wanted t @ find wanted ty + List.fold_left (fun acc t -> find w t @ acc) [] l + | Cic.Cast (t, ty) -> find w t @ find w ty | Cic.Implicit _ -> assert false | Cic.Const (_, esubst) | Cic.Var (_, esubst) | Cic.MutInd (_, _, esubst) | Cic.MutConstruct (_, _, _, esubst) -> - List.fold_left (fun acc (_, t) -> find wanted t @ acc) [] esubst + List.fold_left (fun acc (_, t) -> find w t @ acc) [] esubst | Cic.MutCase (_, _, outty, indterm, patterns) -> - find wanted outty @ find wanted indterm @ - List.fold_left (fun acc p -> find wanted p @ acc) [] patterns + find w outty @ find w indterm @ + List.fold_left (fun acc p -> find w p @ acc) [] patterns | Cic.Fix (_, funl) -> List.fold_left ( - fun acc (_, _, ty, bo) -> find wanted ty @ find wanted bo @ acc + fun acc (_, _, ty, bo) -> find w ty @ find w bo @ acc ) [] funl | Cic.CoFix (_, funl) -> List.fold_left ( - fun acc (_, ty, bo) -> find wanted ty @ find wanted bo @ acc + fun acc (_, ty, bo) -> find w ty @ find w bo @ acc ) [] funl in find wanted t + +let select ~term ~pattern = + let add_ctx i name entry = + (Some (name, entry)) :: i + in + (* i is the number of binder traversed *) + let rec aux i pattern term = + match (pattern, term) with + | Cic.Implicit (Some `Hole), t -> [i,t] + | Cic.Implicit (Some `Type), t -> [] + | Cic.Implicit None,_ -> [] + | Cic.Meta (_, ctxt1), Cic.Meta (_, ctxt2) -> + List.concat + (List.map2 + (fun t1 t2 -> + (match (t1, t2) with Some t1, Some t2 -> aux i t1 t2 | _ -> [])) + ctxt1 ctxt2) + | Cic.Cast (te1, ty1), Cic.Cast (te2, ty2) -> aux i te1 te2 @ aux i ty1 ty2 + | Cic.Prod (Cic.Anonymous, s1, t1), Cic.Prod (name, s2, t2) + | Cic.Lambda (Cic.Anonymous, s1, t1), Cic.Lambda (name, s2, t2) -> + aux i s1 s2 @ aux (add_ctx i name (Cic.Decl s2)) t1 t2 + | Cic.Prod (Cic.Name n1, s1, t1), + Cic.Prod ((Cic.Name n2) as name , s2, t2) + | Cic.Lambda (Cic.Name n1, s1, t1), + Cic.Lambda ((Cic.Name n2) as name, s2, t2) when n1 = n2-> + aux i s1 s2 @ aux (add_ctx i name (Cic.Decl s2)) t1 t2 + | Cic.Prod (name1, s1, t1), Cic.Prod (name2, s2, t2) + | Cic.Lambda (name1, s1, t1), Cic.Lambda (name2, s2, t2) -> [] + | Cic.LetIn (Cic.Anonymous, s1, t1), Cic.LetIn (name, s2, t2) -> + aux i s1 s2 @ aux (add_ctx i name (Cic.Def (s2,None))) t1 t2 + | Cic.LetIn (Cic.Name n1, s1, t1), + Cic.LetIn ((Cic.Name n2) as name, s2, t2) when n1 = n2-> + aux i s1 s2 @ aux (add_ctx i name (Cic.Def (s2,None))) t1 t2 + | Cic.LetIn (name1, s1, t1), Cic.LetIn (name2, s2, t2) -> [] + | Cic.Appl terms1, Cic.Appl terms2 -> auxs i terms1 terms2 + | Cic.Var (_, subst1), Cic.Var (_, subst2) + | Cic.Const (_, subst1), Cic.Const (_, subst2) + | Cic.MutInd (_, _, subst1), Cic.MutInd (_, _, subst2) + | Cic.MutConstruct (_, _, _, subst1), Cic.MutConstruct (_, _, _, subst2) -> + auxs i (List.map snd subst1) (List.map snd subst2) + | Cic.MutCase (_, _, out1, t1, pat1), Cic.MutCase (_ , _, out2, t2, pat2) -> + aux i out1 out2 @ aux i t1 t2 @ auxs i pat1 pat2 + | Cic.Fix (_, funs1), Cic.Fix (_, funs2) -> + List.concat + (List.map2 + (fun (_, _, ty1, bo1) (_, _, ty2, bo2) -> + aux i ty1 ty2 @ aux i bo1 bo2) + funs1 funs2) + | Cic.CoFix (_, funs1), Cic.CoFix (_, funs2) -> + List.concat + (List.map2 + (fun (_, ty1, bo1) (_, ty2, bo2) -> aux i ty1 ty2 @ aux i bo1 bo2) + funs1 funs2) + | x,y -> + raise (Bad_pattern + (Printf.sprintf "Pattern %s versus term %s" + (CicPp.ppterm x) + (CicPp.ppterm y))) + and auxs i terms1 terms2 = (* as aux for list of terms *) + List.concat (List.map2 (fun t1 t2 -> aux i t1 t2) terms1 terms2) + in + aux [] pattern term + +let pattern_of ?(equality=(==)) ~term terms = + let (===) x y = equality x y in + let rec aux t = + match t with + | t when List.exists (fun t' -> t === t') terms -> Cic.Implicit (Some `Hole) + | Cic.Var (uri, subst) -> Cic.Var (uri, aux_subst subst) + | Cic.Meta (i, ctxt) -> + let ctxt = + List.map (function None -> None | Some t -> Some (aux t)) ctxt + in + Cic.Meta (i, ctxt) + | Cic.Cast (t, ty) -> Cic.Cast (aux t, aux ty) + | Cic.Prod (name, s, t) -> Cic.Prod (name, aux s, aux t) + | Cic.Lambda (name, s, t) -> Cic.Lambda (name, aux s, aux t) + | Cic.LetIn (name, s, t) -> Cic.LetIn (name, aux s, aux t) + | Cic.Appl terms -> Cic.Appl (List.map aux terms) + | Cic.Const (uri, subst) -> Cic.Const (uri, aux_subst subst) + | Cic.MutInd (uri, tyno, subst) -> Cic.MutInd (uri, tyno, aux_subst subst) + | Cic.MutConstruct (uri, tyno, consno, subst) -> + Cic.MutConstruct (uri, tyno, consno, aux_subst subst) + | Cic.MutCase (uri, tyno, outty, t, pat) -> + Cic.MutCase (uri, tyno, aux outty, aux t, List.map aux pat) + | Cic.Fix (funno, funs) -> + let funs = + List.map (fun (name, i, ty, bo) -> (name, i, aux ty, aux bo)) funs + in + Cic.Fix (funno, funs) + | Cic.CoFix (funno, funs) -> + let funs = + List.map (fun (name, ty, bo) -> (name, aux ty, aux bo)) funs + in + Cic.CoFix (funno, funs) + | Cic.Rel _ + | Cic.Sort _ + | Cic.Implicit _ -> t + and aux_subst subst = + List.map (fun (uri, t) -> (uri, aux t)) subst + in + aux term +