]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/cic_disambiguation/disambiguate.ml
Bug fixed: case analysis where a case had not the expected number of arguments
[helm.git] / helm / software / components / cic_disambiguation / disambiguate.ml
index ac26903b184165569272747fd10a1219ded135c8..6dd82cc288c42731702bd8b94220d31b5502e8a9 100644 (file)
@@ -35,9 +35,9 @@ module Ast = CicNotationPt
 (* the integer is an offset to be added to each location *)
 exception NoWellTypedInterpretation of
  int *
- ((Token.flocation list * string * string) list *
+ ((Stdpp.location list * string * string) list *
   (DisambiguateTypes.domain_item * DisambiguateTypes.codomain_item) list *
-  Token.flocation option * string Lazy.t * bool) list
+  Stdpp.location option * string Lazy.t * bool) list
 exception PathNotWellFormed
 
   (** raised when an environment is not enough informative to decide *)
@@ -47,7 +47,7 @@ type aliases = bool * DisambiguateTypes.environment
 type 'a disambiguator_input = string * int * 'a
 
 type domain = domain_tree list
-and domain_tree = Node of Token.flocation list * domain_item * domain
+and domain_tree = Node of Stdpp.location list * domain_item * domain
 
 let rec string_of_domain =
  function
@@ -86,7 +86,7 @@ let uniq_domain dom =
  in
   snd (aux [] dom)
 
-let debug = true
+let debug = false
 let debug_print s = if debug then prerr_endline (Lazy.force s) else ()
 
 (*
@@ -105,8 +105,8 @@ let descr_of_domain_item = function
 
 type 'a test_result =
   | Ok of 'a * Cic.metasenv
-  | Ko of Token.flocation option * string Lazy.t
-  | Uncertain of Token.flocation option * string Lazy.t
+  | Ko of Stdpp.location option * string Lazy.t
+  | Uncertain of Stdpp.location option * string Lazy.t
 
 let refine_term metasenv context uri term ugraph ~localization_tbl =
 (*   if benchmark then incr actual_refinements; *)
@@ -172,9 +172,10 @@ let find_in_context name context =
   in
   aux 1 context
 
-let interpretate_term ~(context: Cic.name list) ~env ~uri ~is_path ast
+let interpretate_term ?(create_dummy_ids=false) ~(context: Cic.name list) ~env ~uri ~is_path ast
      ~localization_tbl
 =
+  (* create_dummy_ids shouldbe used only for interpretating patterns *)
   assert (uri = None);
   let rec aux ~localize loc (context: Cic.name list) = function
     | CicNotationPt.AttributedTerm (`Loc loc, term) ->
@@ -216,7 +217,10 @@ let interpretate_term ~(context: Cic.name list) ~env ~uri ~is_path ast
           in
           do_branch' context args
         in
-        let (indtype_uri, indtype_no) =
+        let indtype_uri, indtype_no =
+          if create_dummy_ids then
+            (UriManager.uri_of_string "cic:/fake_indty.con", 0)
+          else
           match indty_ident with
           | Some (indty_ident, _) ->
              (match resolve env (Id indty_ident) () with
@@ -225,12 +229,12 @@ let interpretate_term ~(context: Cic.name list) ~env ~uri ~is_path ast
                  raise (Try_again (lazy "The type of the term to be matched
                   is still unknown"))
               | _ ->
-                raise (Invalid_choice (lazy "The type of the term to be matched is not (co)inductive!")))
+                raise (Invalid_choice (Some loc, lazy "The type of the term to be matched is not (co)inductive!")))
           | None ->
               let fst_constructor =
                 match branches with
                 | ((head, _, _), _) :: _ -> head
-                | [] -> raise (Invalid_choice (lazy "The type of the term to be matched is an inductive type without constructors that cannot be determined"))
+                | [] -> raise (Invalid_choice (Some loc, lazy "The type of the term to be matched is an inductive type without constructors that cannot be determined"))
               in
               (match resolve env (Id fst_constructor) () with
               | Cic.MutConstruct (indtype_uri, indtype_no, _, _) ->
@@ -239,7 +243,57 @@ let interpretate_term ~(context: Cic.name list) ~env ~uri ~is_path ast
                  raise (Try_again (lazy "The type of the term to be matched
                   is still unknown"))
               | _ ->
-                raise (Invalid_choice (lazy "The type of the term to be matched is not (co)inductive!")))
+                raise (Invalid_choice (Some loc, lazy "The type of the term to be matched is not (co)inductive!")))
+        in
+        let branches =
+         match fst(CicEnvironment.get_obj CicUniv.empty_ugraph indtype_uri) with
+            Cic.InductiveDefinition (il,_,_,_) ->
+             let _,_,_,cl =
+              try
+               List.nth il indtype_no
+              with _ -> assert false
+             in
+              let rec count_prod t =
+                match CicReduction.whd [] t with
+                    Cic.Prod (_, _, t) -> 1 + (count_prod t)
+                  | _ -> 0 
+              in 
+              let rec sort branches cl =
+               match cl with
+                  [] ->
+                   if branches = [] then []
+                   else
+                    raise (Invalid_choice
+                     (Some loc,
+                      lazy
+                       ("Unrecognized constructors: " ^
+                        String.concat " "
+                         (List.map (fun ((head,_,_),_) -> head) branches))))
+                | (name,ty)::cltl ->
+                   let rec find_and_remove =
+                    function
+                       [] ->
+                        raise
+                         (Invalid_choice
+                          (Some loc, lazy ("Missing case: " ^ name)))
+                     | ((name',_,_),_) as branch :: tl when name = name' ->
+                        branch,tl
+                     | branch::tl ->
+                        let found,rest = find_and_remove tl in
+                         found, branch::rest
+                   in
+                    let branch,tl = find_and_remove branches in
+                    let (_,_,args),_ = branch in
+                     if List.length args = count_prod ty then
+                      branch::sort tl cltl
+                     else
+                      raise
+                       (Invalid_choice
+                        (Some loc,
+                          lazy ("Wrong number of arguments for " ^ name)))
+              in
+               sort branches cl
+          | _ -> assert false
         in
         Cic.MutCase (indtype_uri, indtype_no, cic_outtype, cic_term,
           (List.map do_branch branches))
@@ -382,7 +436,7 @@ let interpretate_term ~(context: Cic.name list) ~env ~uri ~is_path ast
                     (try
                       List.assoc s ids_to_uris, aux ~localize loc context term
                      with Not_found ->
-                       raise (Invalid_choice (lazy "The provided explicit named substitution is trying to instantiate a named variable the object is not abstracted on"))))
+                       raise (Invalid_choice (Some loc, lazy "The provided explicit named substitution is trying to instantiate a named variable the object is not abstracted on"))))
                   subst
             | None -> List.map (fun uri -> uri, Cic.Implicit None) uris)
           in
@@ -426,10 +480,10 @@ let interpretate_term ~(context: Cic.name list) ~env ~uri ~is_path ast
 *)
                 t
             | _ ->
-              raise (Invalid_choice (lazy "??? Can this happen?"))
+              raise (Invalid_choice (Some loc, lazy "??? Can this happen?"))
            with 
              CicEnvironment.CircularDependency _ -> 
-               raise (Invalid_choice (lazy "Circular dependency in the environment"))))
+               raise (Invalid_choice (None, lazy "Circular dependency in the environment"))))
     | CicNotationPt.Implicit -> Cic.Implicit None
     | CicNotationPt.UserInput -> Cic.Implicit (Some `Hole)
     | CicNotationPt.Num (num, i) -> resolve env (Num i) ~num ()
@@ -459,7 +513,8 @@ let interpretate_path ~context path =
  let localization_tbl = Cic.CicHash.create 23 in
   (* here we are throwing away useful localization informations!!! *)
   fst (
-   interpretate_term ~context ~env:Environment.empty ~uri:None ~is_path:true
+   interpretate_term ~create_dummy_ids:true 
+    ~context ~env:Environment.empty ~uri:None ~is_path:true
     path ~localization_tbl, localization_tbl)
 
 let interpretate_obj ~context ~env ~uri ~is_path obj ~localization_tbl =
@@ -809,7 +864,7 @@ module type Disambiguator =
 sig
   val disambiguate_term :
     ?fresh_instances:bool ->
-    dbd:HMysql.dbd ->
+    dbd:HSql.dbd ->
     context:Cic.context ->
     metasenv:Cic.metasenv ->
     ?initial_ugraph:CicUniv.universe_graph -> 
@@ -824,7 +879,7 @@ sig
 
   val disambiguate_obj :
     ?fresh_instances:bool ->
-    dbd:HMysql.dbd ->
+    dbd:HSql.dbd ->
     aliases:DisambiguateTypes.environment ->(* previous interpretation status *)
     universe:DisambiguateTypes.multiple_environment option ->
     uri:UriManager.uri option ->     (* required only for inductive types *)
@@ -985,7 +1040,7 @@ let foo () =
 in refine_profiler.HExtlib.profile foo ()
         with
         | Try_again msg -> Uncertain (None,msg), ugraph
-        | Invalid_choice msg -> Ko (None,msg), ugraph
+        | Invalid_choice (loc,msg) -> Ko (loc,msg), ugraph
       in
       (* (4) build all possible interpretations *)
       let (@@) (l1,l2,l3) (l1',l2',l3') = l1@l1', l2@l2', l3@l3' in
@@ -1184,7 +1239,7 @@ in refine_profiler.HExtlib.profile foo ()
       disambiguate_thing ~dbd ~context ~metasenv ~initial_ugraph ~aliases
         ~universe ~uri:None ~pp_thing:CicNotationPp.pp_term
         ~domain_of_thing:domain_of_term
-        ~interpretate_thing:interpretate_term
+        ~interpretate_thing:(interpretate_term (?create_dummy_ids:None))
         ~refine_thing:refine_term (text,prefix_len,term)
 
     let disambiguate_obj ?(fresh_instances=false) ~dbd ~aliases ~universe ~uri