]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/cic_unification/cicUnification.ml
- the mathql interpreter is not helm-dependent any more
[helm.git] / helm / ocaml / cic_unification / cicUnification.ml
index 4a2cb243066b0a1b3efb0be2a7f88a54aaee65b4..f7c19073b015755c6be36edceffc8d708db4d82d 100644 (file)
@@ -79,7 +79,11 @@ let delift context metasenv l t =
              ignore (deliftaux k (S.lift m t)) ;
              C.Rel ((position (m-k) l) + k)
          | None -> raise RelToHiddenHypothesis)
-     | C.Var _  as t -> t
+     | C.Var (uri,exp_named_subst) ->
+        let exp_named_subst' =
+         List.map (function (uri,t) -> uri,deliftaux k t) exp_named_subst
+        in
+         C.Var (uri,exp_named_subst')
      | C.Meta (i, l1) as t -> 
         let rec deliftl j =
          function
@@ -103,12 +107,23 @@ let delift context metasenv l t =
      | C.Lambda (n,s,t) -> C.Lambda (n, deliftaux k s, deliftaux (k+1) t)
      | C.LetIn (n,s,t) -> C.LetIn (n, deliftaux k s, deliftaux (k+1) t)
      | C.Appl l -> C.Appl (List.map (deliftaux 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, deliftaux k outty, deliftaux k t,
+     | C.Const (uri,exp_named_subst) ->
+        let exp_named_subst' =
+         List.map (function (uri,t) -> uri,deliftaux k t) exp_named_subst
+        in
+         C.Const (uri,exp_named_subst')
+     | C.MutInd (uri,typeno,exp_named_subst) ->
+        let exp_named_subst' =
+         List.map (function (uri,t) -> uri,deliftaux k t) exp_named_subst
+        in
+         C.MutInd (uri,typeno,exp_named_subst')
+     | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
+        let exp_named_subst' =
+         List.map (function (uri,t) -> uri,deliftaux k t) exp_named_subst
+        in
+         C.MutConstruct (uri,typeno,consno,exp_named_subst')
+     | C.MutCase (sp,i,outty,t,pl) ->
+        C.MutCase (sp, i, deliftaux k outty, deliftaux k t,
          List.map (deliftaux k) pl)
      | C.Fix (i, fl) ->
         let len = List.length fl in
@@ -145,115 +160,154 @@ type substitution = (int * Cic.term) list
    a new substitution which is _NOT_ unwinded. It must be unwinded before
    applying it. *)
  
-let fo_unif_new metasenv context t1 t2 =
-    let module C = Cic in
-    let module R = CicReduction in
-    let module S = CicSubstitution in
-    let rec fo_unif_aux subst context metasenv t1 t2 =  
-    match (t1, t2) with
-         (C.Meta (n,ln), C.Meta (m,lm)) when n=m ->
-           let ok =
-            List.fold_left2
-             (fun b t1 t2 ->
-               b &&
-                match t1,t2 with
-                  None,_
-                | _,None -> true
-                | Some t1', Some t2' ->
-                   (* First possibility:  restriction    *)
-                   (* Second possibility: unification    *)
-                   (* Third possibility:  convertibility *)
-                  R.are_convertible context t1' t2'
-             ) true ln lm
-           in
-            if ok then subst,metasenv else
-             raise UnificationFailed
-       | (C.Meta (n,l), C.Meta (m,_)) when n>m ->
-          fo_unif_aux subst context metasenv t2 t1
-       | (C.Meta (n,l), t)   
-       | (t, C.Meta (n,l)) ->
-          let subst',metasenv' =
-            try
-              let oldt = (List.assoc n subst) in
-              let lifted_oldt = S.lift_meta l oldt in
-              fo_unif_aux subst context metasenv lifted_oldt t
-            with Not_found ->
-prerr_endline ("DELIFT2(" ^ CicPp.ppterm t ^ ")") ; flush stderr ;
-List.iter (function (Some t) -> prerr_endline ("l: " ^ CicPp.ppterm t) | None -> prerr_endline " _ ") l ; flush stderr ;
-prerr_endline "<DELIFT2" ; flush stderr ;
-              let t',metasenv' = delift context metasenv l t in
-              (n, t')::subst, metasenv'
-          in
-           let (_,_,meta_type) = 
-             List.find (function (m,_,_) -> m=n) metasenv' in
-           let tyt = CicTypeChecker.type_of_aux' metasenv' context t in
-            fo_unif_aux subst' context metasenv' (S.lift_meta l meta_type) tyt
-       | (C.Rel _, _)
-       | (_,  C.Rel _) 
-       | (C.Var _, _)
-       | (_, C.Var _) 
-       | (C.Sort _ ,_)
-       | (_, C.Sort _)
-       | (C.Implicit, _)
-       | (_, C.Implicit) -> 
-          if R.are_convertible context t1 t2 then subst, metasenv
-           else raise UnificationFailed
-       | (C.Cast (te,ty), t2) -> fo_unif_aux subst context metasenv te t2
-       | (t1, C.Cast (te,ty)) -> fo_unif_aux subst context metasenv t1 te
-       | (C.Prod (n1,s1,t1), C.Prod (_,s2,t2)) -> 
-          let subst',metasenv' = fo_unif_aux subst context metasenv s1 s2 in
-           fo_unif_aux subst' ((Some (n1,(C.Decl s1)))::context) metasenv' t1 t2
-       | (C.Lambda (n1,s1,t1), C.Lambda (_,s2,t2)) -> 
-           let subst',metasenv' = fo_unif_aux subst context metasenv s1 s2 in
-           fo_unif_aux subst' ((Some (n1,(C.Decl s1)))::context) metasenv' t1 t2
-       | (C.LetIn (_,s1,t1), t2)  
-       | (t2, C.LetIn (_,s1,t1)) -> 
-          fo_unif_aux subst context metasenv t2 (S.subst s1 t1)
-       | (C.Appl l1, C.Appl l2) -> 
-           let lr1 = List.rev l1 in
-           let lr2 = List.rev l2 in
-           let rec fo_unif_l subst metasenv = function
-               [],_
-             | _,[] -> assert false
-             | ([h1],[h2]) ->
-                 fo_unif_aux subst context metasenv h1 h2
-             | ([h],l) 
-             | (l,[h]) ->
-                 fo_unif_aux subst context metasenv h (C.Appl (List.rev l))
-             | ((h1::l1),(h2::l2)) -> 
-                let subst', metasenv' = 
-                  fo_unif_aux subst context metasenv h1 h2
-                 in 
-                 fo_unif_l subst' metasenv' (l1,l2)
-           in
-           fo_unif_l subst metasenv (lr1, lr2) 
-       | (C.Const _, _) 
-       | (_, C.Const _)
-       | (C.Abst _, _) 
-       | (_, C.Abst _) 
-       | (C.MutInd  _, _) 
-       | (_, C.MutInd _)
-       | (C.MutConstruct _, _)
-       | (_, C.MutConstruct _) -> 
-          if R.are_convertible context t1 t2 then subst, metasenv
-           else raise UnificationFailed
-       | (C.MutCase (_,_,_,outt1,t1,pl1), C.MutCase (_,_,_,outt2,t2,pl2))->
-         let subst', metasenv' = 
-          fo_unif_aux subst context metasenv outt1 outt2 in
-         let subst'',metasenv'' = 
-          fo_unif_aux subst' context metasenv' t1 t2 in
-         List.fold_left2 
-          (function (subst,metasenv) ->
-             fo_unif_aux subst context metasenv
-           ) (subst'',metasenv'') pl1 pl2 
-       | (C.Fix _, _)
-       | (_, C.Fix _) 
-       | (C.CoFix _, _)
-       | (_, C.CoFix _) -> 
-          if R.are_convertible context t1 t2 then subst, metasenv
-           else raise UnificationFailed
-       | (_,_) -> raise UnificationFailed
-   in fo_unif_aux [] context metasenv t1 t2;;
+let rec fo_unif_subst subst context metasenv t1 t2 =  
+ let module C = Cic in
+ let module R = CicReduction in
+ let module S = CicSubstitution in
+  match (t1, t2) with
+     (C.Meta (n,ln), C.Meta (m,lm)) when n=m ->
+       let ok =
+        List.fold_left2
+         (fun b t1 t2 ->
+           b &&
+            match t1,t2 with
+               None,_
+             | _,None -> true
+             | Some t1', Some t2' ->
+                (* First possibility:  restriction    *)
+                (* Second possibility: unification    *)
+                (* Third possibility:  convertibility *)
+               R.are_convertible context t1' t2'
+         ) true ln lm
+       in
+        if ok then subst,metasenv else raise UnificationFailed
+   | (C.Meta (n,l), C.Meta (m,_)) when n>m ->
+       fo_unif_subst subst context metasenv t2 t1
+   | (C.Meta (n,l), t)   
+   | (t, C.Meta (n,l)) ->
+       let subst',metasenv' =
+       try
+        let oldt = (List.assoc n subst) in
+        let lifted_oldt = S.lift_meta l oldt in
+         fo_unif_subst subst context metasenv lifted_oldt t
+       with Not_found ->
+        let t',metasenv' = delift context metasenv l t in
+         (n, t')::subst, metasenv'
+       in
+       let (_,_,meta_type) = 
+        List.find (function (m,_,_) -> m=n) metasenv' in
+       let tyt = CicTypeChecker.type_of_aux' metasenv' context t in
+        fo_unif_subst subst' context metasenv' (S.lift_meta l meta_type) tyt
+   | (C.Var (uri1,exp_named_subst1),C.Var (uri2,exp_named_subst2))
+   | (C.Const (uri1,exp_named_subst1),C.Const (uri2,exp_named_subst2)) ->
+      if UriManager.eq uri1 uri2 then
+       fo_unif_subst_exp_named_subst subst context metasenv
+        exp_named_subst1 exp_named_subst2
+      else
+       raise UnificationFailed
+   | C.MutInd (uri1,i1,exp_named_subst1),C.MutInd (uri2,i2,exp_named_subst2) ->
+      if UriManager.eq uri1 uri2 && i1 = i2 then
+       fo_unif_subst_exp_named_subst subst context metasenv
+        exp_named_subst1 exp_named_subst2
+      else
+       raise UnificationFailed
+   | C.MutConstruct (uri1,i1,j1,exp_named_subst1),
+     C.MutConstruct (uri2,i2,j2,exp_named_subst2) ->
+      if UriManager.eq uri1 uri2 && i1 = i2 && j1 = j2 then
+       fo_unif_subst_exp_named_subst subst context metasenv
+        exp_named_subst1 exp_named_subst2
+      else
+       raise UnificationFailed
+   | (C.Rel _, _)
+   | (_,  C.Rel _) 
+   | (C.Var _, _)
+   | (_, C.Var _) 
+   | (C.Sort _ ,_)
+   | (_, C.Sort _)
+   | (C.Implicit, _)
+   | (_, C.Implicit) -> 
+       if R.are_convertible context t1 t2 then
+        subst, metasenv
+       else
+        raise UnificationFailed
+   | (C.Cast (te,ty), t2) -> fo_unif_subst subst context metasenv te t2
+   | (t1, C.Cast (te,ty)) -> fo_unif_subst subst context metasenv t1 te
+   | (C.Prod (n1,s1,t1), C.Prod (_,s2,t2)) -> 
+       let subst',metasenv' = fo_unif_subst subst context metasenv s1 s2 in
+        fo_unif_subst subst' ((Some (n1,(C.Decl s1)))::context) metasenv' t1 t2
+   | (C.Lambda (n1,s1,t1), C.Lambda (_,s2,t2)) -> 
+       let subst',metasenv' = fo_unif_subst subst context metasenv s1 s2 in
+        fo_unif_subst subst' ((Some (n1,(C.Decl s1)))::context) metasenv' t1 t2
+   | (C.LetIn (_,s1,t1), t2)  
+   | (t2, C.LetIn (_,s1,t1)) -> 
+       fo_unif_subst subst context metasenv t2 (S.subst s1 t1)
+   | (C.Appl l1, C.Appl l2) -> 
+       let lr1 = List.rev l1 in
+       let lr2 = List.rev l2 in
+       let rec fo_unif_l subst metasenv =
+        function
+           [],_
+         | _,[] -> assert false
+         | ([h1],[h2]) ->
+             fo_unif_subst subst context metasenv h1 h2
+         | ([h],l) 
+         | (l,[h]) ->
+             fo_unif_subst subst context metasenv h (C.Appl (List.rev l))
+         | ((h1::l1),(h2::l2)) -> 
+            let subst', metasenv' = 
+             fo_unif_subst subst context metasenv h1 h2
+            in 
+             fo_unif_l subst' metasenv' (l1,l2)
+       in
+       fo_unif_l subst metasenv (lr1, lr2) 
+   | (C.Const _, _) 
+   | (_, C.Const _)
+   | (C.MutInd  _, _) 
+   | (_, C.MutInd _)
+   | (C.MutConstruct _, _)
+   | (_, C.MutConstruct _) -> 
+      if R.are_convertible context t1 t2 then
+       subst, metasenv
+      else
+       raise UnificationFailed
+   | (C.MutCase (_,_,outt1,t1,pl1), C.MutCase (_,_,outt2,t2,pl2))->
+       let subst', metasenv' = 
+        fo_unif_subst subst context metasenv outt1 outt2 in
+       let subst'',metasenv'' = 
+       fo_unif_subst subst' context metasenv' t1 t2 in
+       List.fold_left2 
+       (function (subst,metasenv) ->
+          fo_unif_subst subst context metasenv
+        ) (subst'',metasenv'') pl1 pl2 
+   | (C.Fix _, _)
+   | (_, C.Fix _) 
+   | (C.CoFix _, _)
+   | (_, C.CoFix _) -> 
+       if R.are_convertible context t1 t2 then
+        subst, metasenv
+       else
+        raise UnificationFailed
+   | (_,_) ->
+       if R.are_convertible context t1 t2 then
+        subst, metasenv
+       else
+        raise UnificationFailed
+
+and fo_unif_subst_exp_named_subst subst context metasenv
+ exp_named_subst1 exp_named_subst2
+=
+try
+ List.fold_left2
+  (fun (subst,metasenv) (uri1,t1) (uri2,t2) ->
+    assert (uri1=uri2) ;
+    fo_unif_subst subst context metasenv t1 t2
+  ) (subst,metasenv) exp_named_subst1 exp_named_subst2
+with
+e ->
+let uri = UriManager.uri_of_string "cic:/dummy.var" in
+prerr_endline ("@@@: " ^ CicPp.ppterm (Cic.Var (uri,exp_named_subst1)) ^
+" <==> " ^ CicPp.ppterm (Cic.Var (uri,exp_named_subst2))) ; raise e
+;;
 
 (*CSC: ???????????????
 (* m is the index of a metavariable to restrict, k is nesting depth
@@ -335,7 +389,6 @@ CSCSCS
        List.fold_left
          (function metasenv -> aux metasenv k) metasenv l
     | C.Const _
-    | C.Abst _
     | C.MutInd _ 
     | C.MutConstruct _ -> metasenv
     | C.MutCase (_,_,_,outty,t,pl) ->
@@ -389,9 +442,6 @@ let unwind metasenv subst unwinded t =
                let (_,canonical_context,_) = 
                 List.find (function (m,_,_) -> m=i) metasenv
                in
-prerr_endline ("DELIFT(" ^ CicPp.ppterm t' ^ ")") ; flush stderr ;
-List.iter (function (Some t) -> prerr_endline ("l: " ^ CicPp.ppterm t) | None -> prerr_endline " _ ") l ; flush stderr ;
-prerr_endline "<DELIFT" ; flush stderr ;
                 delift canonical_context metasenv' l t'
               in
                unwinded := (i,t')::!unwinded ;
@@ -446,11 +496,34 @@ prerr_endline "<DELIFT" ; flush stderr ;
           | (he', metasenv'') -> C.Appl (he'::tl'),metasenv''
         end
     | C.Appl _ -> assert false
-    | C.Const _
-    | C.Abst _
-    | C.MutInd _
-    | C.MutConstruct _ as t -> t,metasenv
-    | C.MutCase (sp,cookingsno,i,outty,t,pl) ->
+    | C.Const (uri,exp_named_subst) ->
+       let exp_named_subst', metasenv' =
+        List.fold_right
+        (fun (uri,t) (tl,metasenv) ->
+          let t',metasenv' = um_aux metasenv t in
+           (uri,t')::tl, metasenv'
+        ) exp_named_subst ([],metasenv)
+       in
+        C.Const (uri,exp_named_subst'),metasenv'
+    | C.MutInd (uri,typeno,exp_named_subst) ->
+       let exp_named_subst', metasenv' =
+        List.fold_right
+        (fun (uri,t) (tl,metasenv) ->
+          let t',metasenv' = um_aux metasenv t in
+           (uri,t')::tl, metasenv'
+        ) exp_named_subst ([],metasenv)
+       in
+        C.MutInd (uri,typeno,exp_named_subst'),metasenv'
+    | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
+       let exp_named_subst', metasenv' =
+        List.fold_right
+        (fun (uri,t) (tl,metasenv) ->
+          let t',metasenv' = um_aux metasenv t in
+           (uri,t')::tl, metasenv'
+        ) exp_named_subst ([],metasenv)
+       in
+        C.MutConstruct (uri,typeno,consno,exp_named_subst'),metasenv'
+    | C.MutCase (sp,i,outty,t,pl) ->
        let outty',metasenv' = um_aux metasenv outty in
        let t',metasenv'' = um_aux metasenv' t in
        let pl',metasenv''' =
@@ -460,7 +533,7 @@ prerr_endline "<DELIFT" ; flush stderr ;
            p'::pl, metasenv'
         ) pl ([],metasenv'')
        in
-        C.MutCase (sp, cookingsno, i, outty', t', pl'),metasenv'''
+        C.MutCase (sp, i, outty', t', pl'),metasenv'''
     | C.Fix (i, fl) ->
        let len = List.length fl in
        let liftedfl,metasenv' =
@@ -541,12 +614,23 @@ let apply_subst_reducing subst meta_to_reduce t =
            | _,_ -> t'
          end
     | C.Appl _ -> assert false
-    | 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, um_aux outty, um_aux t,
+    | C.Const (uri,exp_named_subst) ->
+       let exp_named_subst' =
+        List.map (function (uri,t) -> (uri,um_aux t)) exp_named_subst
+       in
+        C.Const (uri,exp_named_subst')
+    | C.MutInd (uri,typeno,exp_named_subst) ->
+       let exp_named_subst' =
+        List.map (function (uri,t) -> (uri,um_aux t)) exp_named_subst
+       in
+        C.MutInd (uri,typeno,exp_named_subst')
+    | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
+       let exp_named_subst' =
+        List.map (function (uri,t) -> (uri,um_aux t)) exp_named_subst
+       in
+        C.MutConstruct (uri,typeno,consno,exp_named_subst')
+    | C.MutCase (sp,i,outty,t,pl) ->
+       C.MutCase (sp, i, um_aux outty, um_aux t,
         List.map um_aux pl)
     | C.Fix (i, fl) ->
        let len = List.length fl in
@@ -610,7 +694,7 @@ let apply_subst subst t =
 (* metavariables may have been restricted.                                   *)
 let fo_unif metasenv context t1 t2 =
 prerr_endline "INIZIO FASE 1" ; flush stderr ;
- let subst_to_unwind,metasenv' = fo_unif_new metasenv context t1 t2 in
+ let subst_to_unwind,metasenv' = fo_unif_subst [] context metasenv t1 t2 in
 prerr_endline "FINE FASE 1" ; flush stderr ;
 let res =
   unwind_subst metasenv' subst_to_unwind