]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/interface/cicSubstitution.ml
Initial revision
[helm.git] / helm / interface / cicSubstitution.ml
diff --git a/helm/interface/cicSubstitution.ml b/helm/interface/cicSubstitution.ml
new file mode 100644 (file)
index 0000000..e69a8a9
--- /dev/null
@@ -0,0 +1,115 @@
+let lift n =
+ let rec liftaux k =
+  let module C = Cic in
+   function
+      C.Rel m ->
+       if m < k then
+        C.Rel m
+       else
+        C.Rel (m + n)
+    | C.Var _  as t -> t
+    | C.Meta _ as t -> t
+    | C.Sort _ as t -> t
+    | C.Implicit as t -> t
+    | C.Cast (te,ty) -> C.Cast (liftaux k te, liftaux k ty)
+    | C.Prod (n,s,t) -> C.Prod (n, liftaux k s, liftaux (k+1) t)
+    | C.Lambda (n,s,t) -> C.Lambda (n, liftaux k s, liftaux (k+1) t)
+    | C.Appl l -> C.Appl (List.map (liftaux k) l)
+    | C.Const _ as t -> t
+    | C.Abst _  as t -> t
+    | C.MutInd _ as t -> t
+    | C.MutConstruct _ as t -> t
+    | C.MutCase (sp,cookingsno,i,outty,t,pl) ->
+       C.MutCase (sp, cookingsno, i, liftaux k outty, liftaux k t,
+        List.map (liftaux k) pl)
+    | C.Fix (i, fl) ->
+       let len = List.length fl in
+       let liftedfl =
+        List.map
+         (fun (name, i, ty, bo) -> (name, i, liftaux k ty, liftaux (k+len) bo))
+          fl
+       in
+        C.Fix (i, liftedfl)
+    | C.CoFix (i, fl) ->
+       let len = List.length fl in
+       let liftedfl =
+        List.map
+         (fun (name, ty, bo) -> (name, liftaux k ty, liftaux (k+len) bo))
+          fl
+       in
+        C.CoFix (i, liftedfl)
+ in
+  liftaux 1
+;;
+
+let subst arg =
+ let rec substaux k =
+  let module C = Cic in
+   function
+      C.Rel n as t ->
+       (match n with
+           n when n = k -> lift (k - 1) arg
+         | n when n < k -> t
+         | _            -> C.Rel (n - 1)
+       )
+    | C.Var _ as t  -> t
+    | C.Meta _ as t -> t
+    | C.Sort _ as t -> t
+    | C.Implicit as t -> t
+    | C.Cast (te,ty) -> C.Cast (substaux k te, substaux k ty) (*CSC ??? *)
+    | C.Prod (n,s,t) -> C.Prod (n, substaux k s, substaux (k + 1) t)
+    | C.Lambda (n,s,t) -> C.Lambda (n, substaux k s, substaux (k + 1) t)
+    | C.Appl l -> C.Appl (List.map (substaux k) l)
+    | C.Const _ as t -> t
+    | C.Abst _ as t -> t
+    | C.MutInd _ as t -> t
+    | C.MutConstruct _ as t -> t
+    | C.MutCase (sp,cookingsno,i,outt,t,pl) ->
+       C.MutCase (sp,cookingsno,i,substaux k outt, substaux k t,
+        List.map (substaux k) pl)
+    | C.Fix (i,fl) ->
+       let len = List.length fl in
+       let substitutedfl =
+        List.map
+         (fun (name,i,ty,bo) -> (name, i, substaux k ty, substaux (k+len) bo))
+          fl
+       in
+        C.Fix (i, substitutedfl)
+    | C.CoFix (i,fl) ->
+       let len = List.length fl in
+       let substitutedfl =
+        List.map
+         (fun (name,ty,bo) -> (name, substaux k ty, substaux (k+len) bo))
+          fl
+       in
+        C.CoFix (i, substitutedfl)
+ in
+  substaux 1
+;;
+
+let undebrujin_inductive_def uri =
+ function
+    Cic.InductiveDefinition (dl,params,n_ind_params) ->
+     let dl' =
+      List.map
+       (fun (name,inductive,arity,constructors) ->
+         let constructors' =
+          List.map
+           (fun (name,ty,r) ->
+             let ty' =
+              let counter = ref (List.length dl) in
+               List.fold_right
+                (fun _ ->
+                  decr counter ;
+                  subst (Cic.MutInd (uri,0,!counter))
+                ) dl ty
+             in
+              (name,ty',r)
+           ) constructors
+         in
+          (name,inductive,arity,constructors')
+       ) dl
+      in
+       Cic.InductiveDefinition (dl', params, n_ind_params)
+  | obj -> obj
+;;