From 5bcc152eeaaff4ced1bc356067317848c4159659 Mon Sep 17 00:00:00 2001
From: prak <yoann.prak@cea.fr>
Date: Wed, 28 Nov 2018 16:18:06 +0100
Subject: [PATCH] last commit ?

---
 src/plugins/aorai/data_for_aorai.ml  | 133 ++++++++++++++++++---------
 src/plugins/aorai/data_for_aorai.mli |   2 +-
 src/plugins/aorai/yaparser.mly       |  23 ++++-
 3 files changed, 111 insertions(+), 47 deletions(-)

diff --git a/src/plugins/aorai/data_for_aorai.ml b/src/plugins/aorai/data_for_aorai.ml
index 687776d2cbc..3d708ce52ad 100644
--- a/src/plugins/aorai/data_for_aorai.ml
+++ b/src/plugins/aorai/data_for_aorai.ml
@@ -245,20 +245,18 @@ Graph.Path.BellmanFord
     let zero = 0
     end
   ) *)
+type table = varinfo Datatype.String.Map.t
+
+let global_table = ref Datatype.String.Map.empty (*mettre dans .mli*)
 
 let auto_graph = Automata_graph.create()
 
-(* val setGraph t -> Promelaast.state list -> (Promelaast.typed_condition * Promelaast.action) Promelaast.trans list -> unit *)
+(* val setGraph t -> (Promelaast.typed_condition * Promelaast.action) Promelaast.trans list -> unit *)
 
-let rec setGraph g (*state*) trans = 
-  (*match state with
-  | h::t -> Automata_graph.add_vertex g h ; setGraph g t trans
-  | [] -> *)
-  (
+let setGraph (*state*) trans = 
     match trans with
-    | ht::tt -> Automata_graph.add_edge_e g (ht.start, ht, ht.stop) ; setGraph g tt
-    | [] -> failwith "Automata does not have any transition"
-  )
+    | _::_ -> List.iter (fun a -> Automata_graph.add_edge_e auto_graph (a.start, a, a.stop)) trans
+    | [] -> Aorai_option.abort "Automata does not have any transition"
 
 (*let rec BFS g v = 
   let l = (True, v)::l in 
@@ -280,7 +278,7 @@ let parcoursProfondeur g v =
           ) succ_list
   in aux g v tmp_graph
 *)
-(* Version tmpgraph *)
+(* Version tmpgraph 
 let rec parPro g v tmpg =
     let succ_list = Automata_graph.succ g v in 
         List.iter 
@@ -288,7 +286,7 @@ let rec parPro g v tmpg =
             if not (Automata_graph.mem_vertex tmpg a) then
               Automata_graph.add_vertex tmpg a; parPro g a tmpg
           ) succ_list
-
+*)
 let rec delPath g a tmp = 
    match (Automata_graph.pred g a) with 
     | h::[] -> 
@@ -313,10 +311,10 @@ let getInit g =
   Automata_graph.fold_vertex (let aux v l = 
     if (Automata_graph.pred g v = []) then v::l else l in aux ) g []
     
-let getVertexFromLabel g f = Automata_graph.fold_edges_e f g [] 
+(*let getVertexFromLabel g f = Automata_graph.fold_edges_e f g []*) 
 
 (*val pathVtoV Automata_graph -> vertex -> vertex -> Automata_graph*)
-(*make a sub-graph from g in tmp with only paths from v1 to v2*)
+(*make an imperative sub-graph from g in tmp with only paths from v1 to v2*)
 let rec pathVtoV g v1 v2 tmp =
     let succ_list = Automata_graph.succ g v1 in
     if not (Automata_graph.mem_vertex tmp v1) then
@@ -325,6 +323,49 @@ let rec pathVtoV g v1 v2 tmp =
           | h::t -> Automata_graph.add_edge_e tmp (Automata_graph.find_edge g v1 h); if v1 != v2 then List.iter (fun a -> pathVtoV g a v2 tmp) (h::t) (*applies pathVtoV to all successors of v1*)
       )
 
+let inspect_typed_condition tc = 
+  let result = ref [] in 
+  let visitor = object 
+    inherit Visitor.frama_c_inplace
+    method!vlogic_var_use lv = 
+      if Datatype.String.Map.exists (fun _ vi -> (Cil.cvar_to_lvar vi) = lv ) (!global_table) then 
+        result := (lv::!result);
+        Cil.SkipChildren
+  end in
+  let rec aux = 
+    function
+    | TAnd (tt, ttt) -> aux tt; aux ttt
+    | TOr (tt, ttt) -> aux tt; aux ttt
+    | TRel (_, tt1, tt2) -> ignore (Visitor.visitFramacTerm visitor tt1); ignore (Visitor.visitFramacTerm visitor tt2)
+    | _ -> ()
+  in aux tc; !result
+
+let checkAutomataVar g =  
+  let init = List.hd (getInit g) in
+  Automata_graph.iter_edges_e ( fun e ->
+     match e with
+     |(vert, {cross = (tc, _)}, _) -> 
+     List.iter ( fun var_inf -> 
+        let tmp = Automata_graph.create() in pathVtoV g init vert tmp; 
+        if (Automata_graph.fold_edges_e (fun l _ -> 
+            match l with 
+              | ( _,{ cross = (_, ll) ; _ }, _ ) -> begin
+                List.exists (fun a -> match a with 
+                  | Copy_value((TVar(cc),_), _) ->
+                  begin
+                    if cc = var_inf then true
+                    else false
+                  end
+                  | _ -> true ) ll
+              end
+              (*| _ -> true *)
+            ) tmp true
+          ) then ()
+        else Aorai_option.abort "Variable is not defined on any path"
+      ) (inspect_typed_condition tc)
+      (*| _ -> ()*)
+    ) g 
+  
 (* Each transition with a parametrized cross condition (call param access or return value access) has its parametrized part stored in this array. *)
 let cond_of_parametrizedTransitions = ref (Array.make (1) [[]])
 
@@ -541,13 +582,7 @@ type current_event =
               repr of the stack does not take into account
               this particular event. *)
 
-(*TODO*)
-module StringMap = Datatype.String.Map
-
-(*type table = expression StringMap.t
-*)
-type table = varinfo StringMap.t
-
+(*New definition of environment to be able to handle metavariable*)
 type env = { event:current_event list ; var:table}
 
 let add_current_event event env cond =
@@ -701,43 +736,43 @@ let check_one top info counter s =
   StringMap.find s (env.var) *)
 
 let find_avar s env =
-try StringMap.find s (env.var)
-with Not_found -> let tmp = Automata_graph.create() in 
+try Datatype.String.Map.find s (env.var)
+with Not_found -> Aorai_option.abort "Aorai var not found"
+
+(*let tmp = Automata_graph.create() in 
   let ve = getVertexFromLabel auto_graph (
     fun e l -> match e with
-    |(_, ee, _) -> begin
-      List.fold_left (fun a sa -> 
-        match a with 
-        | TRel(_, { term_type = Lvar(t) ; _ }, _) -> if t = s then e::[] else []
-        | _ -> []
-        ) (fst ee.cross) []
-        end
+    |(vert, {cross = (TRel(_, { term_type = Lvar(t) ; _ }, _), _); _}, _) ->  
+        if t = s then (vert::l) else [] (*l is empty*)
     | _ -> Aorai_option.abort "Not a transition"
-    ) in match ve with 
+    ) in 
+    match ve with 
     | hh::[] -> 
+    begin
       match getInit auto_graph with 
-      | h::[] -> begin pathVtoV auto_graph g h hh tmp; let res = Automata_graph.fold_edges_e 
+      | h::[] -> begin pathVtoV auto_graph h hh tmp; let res = Automata_graph.fold_edges_e 
       (
         fun e l -> 
         match e with
           |(_, ee, _) -> 
           begin
-            List.fold_left (fun a sa -> 
+            List.fold_left (fun sa a -> 
               match a with 
-                | Copy_value((Tvar(lvar),_), { term_type = Ctype(t); _}) -> 
-                  let v = Cil.makeGlobalVar (get_fresh ("aorai_" ^ s)) t in if (lvar = Cil.cvar_to_lvar v) then [v] else []
+                | Copy_value((TVar(lvar),_), { term_type = Ctype(t); _}) -> 
+                  let v = Cil.makeGlobalVar (get_fresh ("aorai_" ^ s)) t in if (lvar = Cil.cvar_to_lvar v) then (v::l) else sa (*l and sa are empty lists*)
                 | _ -> []    
-            ) (snd ee.cross) []
-            end
-            | _ -> Aorai_option.abort "Not a transition"
+            ) [] (snd ee.cross)
+          end
+          (*| _ -> Aorai_option.abort "Not a transition"*)
         ) tmp [] in 
           match res with
           | h::[] -> h
           | _ -> Aorai_option.abort "Aorai var not found" 
         end
-        | _ -> Aorai_option.abort "Not a unique beginning"
-      | _ -> Aorai_option.abort "Multiple transition corresponding"
-(*with Not_found -> Aorai_option.abort "Aorai var not found" *)
+      | _ -> Aorai_option.abort "Not a unique beginning"
+    end
+    | _::_::_ -> Aorai_option.abort "Multiple transition corresponding"
+    | [] -> Aorai_option.abort "No current transition" *)
 
 let find_in_env env counter s =
   let current, stack =
@@ -855,7 +890,7 @@ module LTyping = Logic_typing.Make(C_logic_env)
 
 let type_expr env ?tr ?current e =
   let loc = Cil_datatype.Location.unknown in
-  let rec aux env cond e =
+  let rec aux env cond e (*t pour le type attendu*)=
     match e with
         PVar s ->
           let var = find_in_env env current s in
@@ -1053,8 +1088,13 @@ let type_cond needs_pebble env tr cond =
       begin
         let env, term_tmp, c1 = type_expr env ~tr ?current e in
         match term_tmp.term_type with
-          | Ctype(t) -> let v = Cil.makeGlobalVar (get_fresh ("aorai_" ^ s)) t in { event = env.event; var = (StringMap.add s v env.var)}, (c1, [Copy_value((TVar(Cil.cvar_to_lvar v), TNoOffset), term_tmp )])
-        (*Cil.Cvar_to_lvar v pour en faire une logic var puis il faut le transformer en term_lval*)
+          | Ctype(t) -> begin
+            let v = Cil.makeGlobalVar (get_fresh ("aorai_" ^ s)) t in
+            match (Datatype.String.Map.find s !global_table) with
+            | { vtype = tt; _} -> if tt = t then 
+            env, (*{ event = env.event; var = (Datatype.String.Map.add s v env.var)},*) (c1, [Copy_value((TVar(Cil.cvar_to_lvar v), TNoOffset), term_tmp )])
+            else Aorai_option.abort "Metavariable %s's type is not the same as declared" s
+          end
           | _ ->  Aorai_option.abort "Not the right type"
       end
       else
@@ -1610,7 +1650,7 @@ let type_cond_auto (st,tr as auto) =
     if List.memq st acc then acc else st::acc
   in
   let type_trans (states,transitions,add_reject) tr =
-    let (intermediate_states, trans, needs_reject) = type_trans auto {event = []; var = StringMap.empty } tr in (*TODO*)
+    let (intermediate_states, trans, needs_reject) = type_trans auto {event = []; var = !global_table } tr in (*TODO*)
     Aorai_option.debug
       "Considering parsed transition %s -> %s" tr.start.name tr.stop.name;
     Aorai_option.debug
@@ -1688,7 +1728,10 @@ let setAutomata auto =
   then
     (* all transitions have a true parameterized guard, i.e. [[]] *)
     cond_of_parametrizedTransitions :=
-      Array.make (getNumberOfTransitions  ()) [[]] ; setGraph auto_graph (snd !automata) (*TODO*)
+      Array.make (getNumberOfTransitions  ()) [[]] ;
+  setGraph (snd auto); 
+  checkAutomataVar auto_graph
+   (*TODO*)
 
 let getState num = List.find (fun st -> st.nums = num) (fst !automata)
 
diff --git a/src/plugins/aorai/data_for_aorai.mli b/src/plugins/aorai/data_for_aorai.mli
index 5205169d045..908c003cf9a 100644
--- a/src/plugins/aorai/data_for_aorai.mli
+++ b/src/plugins/aorai/data_for_aorai.mli
@@ -56,7 +56,7 @@ val add_logic : string -> Cil_types.logic_info -> unit
 (** *)
 val get_logic : string -> Cil_types.logic_info
 
-
+val global_table : varinfo Datatype.String.Map.t ref
 (** *)
 val add_predicate : string -> Cil_types.logic_info -> unit
 
diff --git a/src/plugins/aorai/yaparser.mly b/src/plugins/aorai/yaparser.mly
index 573260dd5d1..782e4c4f783 100644
--- a/src/plugins/aorai/yaparser.mly
+++ b/src/plugins/aorai/yaparser.mly
@@ -27,10 +27,12 @@
 
 /* Originated from http://www.ltl2dstar.de/down/ltl2dstar-0.4.2.zip  */
 %{
+open Cil_types
 open Logic_ptree
 open Promelaast
 open Bool3
 
+
 let to_seq c =
   [{ condition = Some c;
      nested = [];
@@ -70,6 +72,15 @@ let prefetch_and_create_state name =
 
 type pre_cond = Behavior of string | Pre of Promelaast.condition
 
+(*let type_table = StringMap.empty*)
+
+let stringToType s = 
+  match s with
+    | "int" -> TInt(IInt, [])
+    | "char" -> TInt(IChar, [])
+    | "long" -> TInt(ILong, [])
+    | _ -> Aorai_option.abort "Metavariable type does not exist"
+
 %}
 
 %token CALL_OF  RETURN_OF  CALLORRETURN_OF
@@ -123,6 +134,11 @@ main
                 with Not_found ->
                   Aorai_option.abort "no state '%s'\n" id) ids
          | "deterministic" -> Aorai_option.Deterministic.set true;
+         | "metavar" -> begin
+            match ids with
+            | h::[t] -> let v = Cil.makeGlobalVar (Data_for_aorai.get_fresh ("aorai_" ^ h)) (stringToType t) in Data_for_aorai.global_table := Datatype.String.Map.add h v (!Data_for_aorai.global_table)
+            | _ -> Aorai_option.abort "Missing or too many arguments in metavariable definition"
+            end
          | oth      -> Aorai_option.abort "unknown option '%s'\n" oth
     ) $1;
     let states=
@@ -168,6 +184,7 @@ option
 opt_identifiers
   : /* empty */ { [] }
   | COLON id_list { $2 }
+/*  | COLON metavar { $2 } */
   ;
 
 id_list
@@ -180,6 +197,10 @@ states
   | state { $1 }
   ;
 
+/*metavar
+  : IDENTIFIER COMMA IDENTIFIER { $1::[$3] }
+metavar : x, int*/
+
 state
   : IDENTIFIER COLON transitions SEMI_COLON {
       let start_state = fetch_and_create_state $1 in
@@ -304,7 +325,7 @@ single_cond:
   | RETURN_OF  LPAREN IDENTIFIER RPAREN { PReturn $3 }
   | TRUE { PTrue }
   | FALSE { PFalse }
-  /*TODO ajouter le cas du Not (... and ...) entre autre*/
+  /*TODO*/
   | NOT single_cond { match $2 with
     | AfVar(_, _) -> Aorai_option.abort "Not corresponding to program" (*Parsing.symbol_end_pos*)
     | _ -> PNot $2 }
-- 
GitLab