From: Stefano Zacchiroli Date: Tue, 11 Jan 2005 16:01:46 +0000 (+0000) Subject: - added support for contexts (terms with holes) X-Git-Tag: V_0_1_0~150 X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=commitdiff_plain;h=b24d13c4dcc96a204951857ddfa18c5ded4cecd0;p=helm.git - added support for contexts (terms with holes) - added CicUtil.pack/unpack to pack/unpack several terms in a single term - added CicUtil.strip_prods to removed a given number of head prods from a term - added CicUtil.context_of/select to create contexts/select a subterm matching a context --- diff --git a/helm/ocaml/cic/cic.ml b/helm/ocaml/cic/cic.ml index c997d99ca..4f7051688 100644 --- a/helm/ocaml/cic/cic.ml +++ b/helm/ocaml/cic/cic.ml @@ -39,7 +39,7 @@ type id = string (* the abstract type of the (annotated) node identifiers *) type 'term explicit_named_substitution = (UriManager.uri * 'term) list -type implicit_annotation = [ `Closed | `Type ] +type implicit_annotation = [ `Closed | `Type | `Hole ] type anntarget = Object of annobj (* if annobj is a Constant, this is its type *) @@ -58,7 +58,7 @@ and name = Name of string | Anonymous and term = - Rel of int (* DeBrujin index *) + Rel of int (* DeBrujin index, 1 based*) | Var of UriManager.uri * (* uri, *) term explicit_named_substitution (* explicit named subst. *) | Meta of int * (term option) list (* numeric id, *) @@ -94,7 +94,7 @@ and obj = | CurrentProof of string * metasenv * (* name, conjectures, *) term * term * UriManager.uri list (* value, type, parameters *) | InductiveDefinition of inductiveType list * (* inductive types, *) - UriManager.uri list * int (* parameters, n ind. pars *) + UriManager.uri list * int (* params, left params no *) and inductiveType = string * bool * term * (* typename, inductive, arity *) constructor list (* constructors *) diff --git a/helm/ocaml/cic/cicUtil.ml b/helm/ocaml/cic/cicUtil.ml index 1c5d603ca..5e0d6d4a9 100644 --- a/helm/ocaml/cic/cicUtil.ml +++ b/helm/ocaml/cic/cicUtil.ml @@ -160,3 +160,96 @@ let term_of_uri s = | Failure _ | Not_found -> raise (UriManager.IllFormedUri s) +let select ~term ~context = + let rec aux context term = + match (context, term) with + | Cic.Implicit (Some `Hole), t -> [t] + | Cic.Meta (_, ctxt1), Cic.Meta (_, ctxt2) -> + List.concat + (List.map2 + (fun t1 t2 -> + (match (t1, t2) with Some t1, Some t2 -> aux t1 t2 | _ -> [])) + ctxt1 ctxt2) + | Cic.Cast (te1, ty1), Cic.Cast (te2, ty2) -> aux te1 te2 @ aux ty1 ty2 + | Cic.Prod (_, s1, t1), Cic.Prod (_, s2, t2) + | Cic.Lambda (_, s1, t1), Cic.Lambda (_, s2, t2) + | Cic.LetIn (_, s1, t1), Cic.LetIn (_, s2, t2) -> aux s1 s2 @ aux t1 t2 + | Cic.Appl terms1, Cic.Appl terms2 -> auxs 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 (List.map snd subst1) (List.map snd subst2) + | Cic.MutCase (_, _, out1, t1, pat1), Cic.MutCase (_ , _, out2, t2, pat2) -> + aux out1 out2 @ aux t1 t2 @ auxs pat1 pat2 + | Cic.Fix (_, funs1), Cic.Fix (_, funs2) -> + List.concat + (List.map2 + (fun (_, _, ty1, bo1) (_, _, ty2, bo2) -> aux ty1 ty2 @ aux bo1 bo2) + funs1 funs2) + | Cic.CoFix (_, funs1), Cic.CoFix (_, funs2) -> + List.concat + (List.map2 + (fun (_, ty1, bo1) (_, ty2, bo2) -> aux ty1 ty2 @ aux bo1 bo2) + funs1 funs2) + | _ -> assert false + and auxs terms1 terms2 = (* as aux for list of terms *) + List.concat (List.map2 aux terms1 terms2) + in + aux context term + +let context_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 + +let pack terms = + List.fold_right + (fun term acc -> Cic.Prod (Cic.Anonymous, term, acc)) + terms (Cic.Sort (Cic.Type (CicUniv.fresh ()))) + +let rec unpack = function + | Cic.Prod (Cic.Anonymous, term, Cic.Sort (Cic.Type _)) -> [term] + | Cic.Prod (Cic.Anonymous, term, tgt) -> term :: unpack tgt + | _ -> assert false + +let rec strip_prods n = function + | t when n = 0 -> t + | Cic.Prod (_, _, tgt) when n > 0 -> strip_prods (n-1) tgt + | _ -> failwith "not enough prods" + diff --git a/helm/ocaml/cic/cicUtil.mli b/helm/ocaml/cic/cicUtil.mli index ba9bab63d..cfd2d813a 100644 --- a/helm/ocaml/cic/cicUtil.mli +++ b/helm/ocaml/cic/cicUtil.mli @@ -39,3 +39,25 @@ val is_meta_closed : Cic.term -> bool (** @raise UriManager.IllFormedUri *) val term_of_uri: string -> Cic.term + (** packing/unpacking of several terms into a single one *) +val pack: Cic.term list -> Cic.term +val unpack: Cic.term -> Cic.term list + + (** @raise Failure "not enough prods" *) +val strip_prods: int -> Cic.term -> Cic.term + +(** {2 Contexts} + * A context is a Cic term in which Cic.Implicit terms annotated with `Hole + * appears *) + +(** create a context from a term and a list of subterm. +* @param equality equality function used while walking the term. Defaults to +* physical equality (==) *) +val context_of: + ?equality:(Cic.term -> Cic.term -> bool) -> term:Cic.term -> Cic.term list -> + Cic.term + +(** select all subterms of a given term matching a given context (i.e. subtrees +* rooted at context's holes *) +val select: term:Cic.term -> context:Cic.term -> Cic.term list +