summaryrefslogtreecommitdiff
path: root/interpret
diff options
context:
space:
mode:
Diffstat (limited to 'interpret')
-rw-r--r--interpret/interpret.ml171
1 files changed, 101 insertions, 70 deletions
diff --git a/interpret/interpret.ml b/interpret/interpret.ml
index d141bc6..373ed5f 100644
--- a/interpret/interpret.ml
+++ b/interpret/interpret.ml
@@ -20,18 +20,63 @@ let find_node_decl p id =
| AST_node_decl d -> d
| _ -> assert false
+(* Utility : build subscopes of equation ; extract pre declarations *)
+
+(* subscopes :
+ prog -> expr ext -> (id * eqs * (id * expr ext) list) list
+*)
+let rec subscopes p e = match fst e with
+ | AST_identifier _ | AST_int_const _ | AST_real_const _ | AST_bool_const _ -> []
+ | AST_unary (_, e') | AST_pre (e', _) | AST_not e' -> subscopes p e'
+ | AST_binary(_, e1, e2) | AST_binary_rel (_, e1, e2) | AST_binary_bool (_, e1, e2)
+ | AST_arrow(e1, e2) ->
+ subscopes p e1 @ subscopes p e2
+ | AST_if(e1, e2, e3) ->
+ subscopes p e1 @ subscopes p e2 @ subscopes p e3
+ | AST_instance((f, _), args, id) ->
+ let more = List.flatten (List.map (subscopes p) args) in
+ let (node, _) = find_node_decl p f in
+ let args_x = List.map2 (fun id arg -> id, arg) node.args args in
+ (id, node.body, args_x)::more
+
+(* extract_pre : expr ext -> (id * expr ext) list *)
+let rec extract_pre e = match fst e with
+ | AST_identifier _ | AST_int_const _ | AST_real_const _ | AST_bool_const _ -> []
+ | AST_unary (_, e') | AST_not e' -> extract_pre e'
+ | AST_binary(_, e1, e2) | AST_binary_rel (_, e1, e2) | AST_binary_bool (_, e1, e2)
+ | AST_arrow(e1, e2) ->
+ extract_pre e1 @ extract_pre e2
+ | AST_if(e1, e2, e3) ->
+ extract_pre e1 @ extract_pre e2 @ extract_pre e3
+ | AST_instance((f, _), args, id) ->
+ List.flatten (List.map extract_pre args)
+ | AST_pre(e', n) ->
+ (n, e')::(extract_pre e')
+
+
(* Expression evaluation *)
+type eval_env = {
+ p: prog;
+ c: calc_map;
+ scopes: string list;
+}
+
(*
- eval_expr : prog -> calc_map -> state -> string -> expr ext -> (state * value)
+ eval_expr : eval_env -> string -> expr ext -> (state * value)
*)
-let rec eval_expr p c scope st exp =
- let sub_eval = eval_expr p c scope in
+let rec eval_expr env st exp =
+ let sub_eval = eval_expr env in
+ let scope = List.hd env.scopes in
match fst exp with
| AST_identifier (id, _) ->
- begin try let st, v = get_var st c (scope^"/"^id) in st, [v]
- with No_variable _ -> let st, v = get_var st c ("cst/"^id) in st, [v]
- end
+ let rec aux = function
+ | [] ->
+ let st, v = get_var st env.c ("cst/"^id) in st, [v]
+ | sc::q ->
+ try let st, v = get_var st env.c (sc^"/"^id) in st, [v]
+ with No_variable _ -> aux q
+ in aux env.scopes
(* on numerical values *)
| AST_int_const (i, _) -> st, [VInt (int_of_string i)]
| AST_real_const (r, _) -> st, [VReal (float_of_string r)]
@@ -111,16 +156,18 @@ let rec eval_expr p c scope st exp =
| _ -> type_error "Invalid condition in if."
end
| AST_instance((f, _), args, nid) ->
- let (n, _) = find_node_decl p f in
+ let (n, _) = find_node_decl env.p f in
List.fold_left
- (fun (st, vs) (_, (id,_), _) -> let st, v = get_var st c (scope^"/"^nid^"/"^id) in
+ (fun (st, vs) (_, (id,_), _) ->
+ let st, v = get_var st env.c (scope^"/"^nid^"/"^id) in
st, vs @ [v])
(st, []) n.ret
(* Constant calculation *)
let rec calc_const p d st c =
- match eval_expr p c "cst" st d.value with
+ let env = { p = p; c = c; scopes = ["cst"] } in
+ match eval_expr env st d.value with
| st, [v] -> VarMap.add ("cst/"^d.name) v st
| _ -> type_error ("Cannot assign tuple to constant" ^ d.name)
@@ -140,46 +187,41 @@ let program_consts p =
VarMap.empty
cdecl
-(* Program execution *)
-
-(* subscopes :
- prog -> expr ext -> (id * eqs * (id * expr ext) list) list
-*)
-let rec subscopes p e = match fst e with
- | AST_identifier _ | AST_int_const _ | AST_real_const _ | AST_bool_const _ -> []
- | AST_unary (_, e') | AST_pre (e', _) | AST_not e' -> subscopes p e'
- | AST_binary(_, e1, e2) | AST_binary_rel (_, e1, e2) | AST_binary_bool (_, e1, e2)
- | AST_arrow(e1, e2) ->
- subscopes p e1 @ subscopes p e2
- | AST_if(e1, e2, e3) ->
- subscopes p e1 @ subscopes p e2 @ subscopes p e3
- | AST_instance((f, _), args, id) ->
- let more = List.flatten (List.map (subscopes p) args) in
- let (node, _) = find_node_decl p f in
- let args_x = List.map2 (fun id arg -> id, arg) node.args args in
- (id, node.body, args_x)::more
+(* get initial state for program *)
+let program_init_state p root_node =
+ let (n, _) = find_node_decl p root_node in
+ let rec aux st p scope eqs =
+ let st = VarMap.add (scope^"/init") (VBool true) st in
+ let add_subscopes =
+ List.fold_left (fun st (ss_id, ss_eqs, _) -> aux st p (scope^"/"^ss_id) ss_eqs)
+ in
+ let add_eq st eq = match fst eq with
+ | AST_assign(_, e) -> add_subscopes st (subscopes p e)
+ | AST_assume _ | AST_guarantee _ -> st
+ | AST_automaton (aid, astates, ret) ->
+ let (initial, _) = List.find (fun (s, _) -> s.initial) astates in
+ let st = VarMap.add (scope^":"^aid^".state") (VState initial.name) st in
+ let add_astate st ((astate:Ast.state), _) =
+ aux st p (scope^":"^aid^"."^astate.name) astate.body
+ in
+ List.fold_left add_astate st astates
+ | AST_activate _ -> not_implemented "program_init_state activate"
+ in
+ List.fold_left add_eq st eqs
+ in
+ aux (program_consts p) p "" n.body
-(* extract_pre : expr ext -> (id * expr ext) list *)
-let rec extract_pre e = match fst e with
- | AST_identifier _ | AST_int_const _ | AST_real_const _ | AST_bool_const _ -> []
- | AST_unary (_, e') | AST_not e' -> extract_pre e'
- | AST_binary(_, e1, e2) | AST_binary_rel (_, e1, e2) | AST_binary_bool (_, e1, e2)
- | AST_arrow(e1, e2) ->
- extract_pre e1 @ extract_pre e2
- | AST_if(e1, e2, e3) ->
- extract_pre e1 @ extract_pre e2 @ extract_pre e3
- | AST_instance((f, _), args, id) ->
- List.flatten (List.map extract_pre args)
- | AST_pre(e', n) ->
- (n, e')::(extract_pre e')
+(* Program execution *)
(* build calc map *)
-let rec build_prog_ccmap p scope eqs st =
+let rec build_prog_ccmap p scopes eqs st =
+ let scope = List.hd scopes in
let add_eq c eq = match fst eq with
| AST_assign(vars, e) ->
let calc st c =
- let st, vals = eval_expr p c scope st e in
+ let env = { p = p; c = c; scopes = scopes } in
+ let st, vals = eval_expr env st e in
List.fold_left2
(fun st (id,_) v -> VarMap.add (scope^"/"^id) v st)
st vars vals
@@ -187,15 +229,13 @@ let rec build_prog_ccmap p scope eqs st =
let c = List.fold_left (fun c (id, _) -> VarMap.add (scope^"/"^id) (F calc) c) c vars in
let add_subscope c (ss_id, ss_eqs, ss_args) =
- let c = VarMap.merge (fun _ a b -> match a, b with
- | Some x, None -> Some x
- | None, Some y -> Some y
- | _ -> assert false) c
- (build_prog_ccmap p (scope^"/"^ss_id) ss_eqs st)
+ let c = VarMap.merge disjoint_union c
+ (build_prog_ccmap p [scope^"/"^ss_id] ss_eqs st)
in
let add_v c ((_, (id, _), _), eq) =
let calc st c =
- let st, vals = eval_expr p c scope st eq in
+ let env = { p = p; c = c; scopes = scopes } in
+ let st, vals = eval_expr env st eq in
match vals with
| [v] -> VarMap.add (scope^"/"^ss_id^"/"^id) v st
| _ -> type_error "invalid arity"
@@ -207,15 +247,18 @@ let rec build_prog_ccmap p scope eqs st =
List.fold_left add_subscope c (subscopes p e)
| AST_assume _ | AST_guarantee _ -> c
| AST_automaton _ -> not_implemented "build_prog_ccmap for automaton"
+ | AST_activate _ -> not_implemented "build_prog_ccmap for activate"
in
List.fold_left add_eq VarMap.empty eqs
-let extract_next_state active p scope eqs st ccmap =
+let extract_next_state active env eqs st =
let csts = VarMap.filter
(fun k _ -> String.length k > 4 && String.sub k 0 4 = "cst/")
st
in
- let rec aux active scope eqs st nst =
+ let rec aux active scopes eqs st nst =
+ let scope = List.hd env.scopes in
+
let r = VarMap.add (scope^"/init")
(if active then VBool false
else try VarMap.find (scope^"/init") st with Not_found -> assert false)
@@ -223,13 +266,13 @@ let extract_next_state active p scope eqs st ccmap =
in
let add_subscopes active =
List.fold_left (fun (st, nst) (ss_id, ss_eqs, _) ->
- aux active (scope^"/"^ss_id) ss_eqs st nst)
+ aux active [scope^"/"^ss_id] ss_eqs st nst)
in
let add_eq (st, nst) eq = match fst eq with
| AST_assign(vars, e) ->
- let st, nst = add_subscopes active (st, nst) (subscopes p e) in
+ let st, nst = add_subscopes active (st, nst) (subscopes env.p e) in
List.fold_left (fun (st, nst) (pn, pe) ->
- let st, v = if active then eval_expr p ccmap scope st pe
+ let st, v = if active then eval_expr { env with scopes = scopes } st pe
else st,
try match VarMap.find (scope^"/"^pn) st with VPrevious x -> x | _ -> []
with Not_found -> []
@@ -238,24 +281,11 @@ let extract_next_state active p scope eqs st ccmap =
(st, nst) (extract_pre e)
| AST_assume _ | AST_guarantee _ -> st, nst
| AST_automaton _ -> not_implemented "extract_next_state automaton"
+ | AST_activate _ -> not_implemented "extract_next_state activate"
in
List.fold_left add_eq (st, r) eqs
- in aux active scope eqs st csts
+ in aux active env.scopes eqs st csts
-let program_init_state p root_node =
- let (n, _) = find_node_decl p root_node in
- let rec aux st p scope eqs =
- let st = VarMap.add (scope^"/init") (VBool true) st in
- let add_subscopes =
- List.fold_left (fun st (ss_id, ss_eqs, _) -> aux st p (scope^"/"^ss_id) ss_eqs)
- in
- List.fold_left (fun st eq -> match fst eq with
- | AST_assign(_, e) -> add_subscopes st (subscopes p e)
- | AST_assume _ | AST_guarantee _ -> st
- | AST_automaton _ -> not_implemented "prog_init_state aux automaton")
- st eqs
- in
- aux (program_consts p) p "" n.body
let program_step p st inputs root_node =
@@ -263,7 +293,7 @@ let program_step p st inputs root_node =
let st = List.fold_left
(fun st (n, v) -> VarMap.add ("/"^n) v st) st inputs in
- let ccmap = build_prog_ccmap p "" n.body st in
+ let ccmap = build_prog_ccmap p [""] n.body st in
let st = List.fold_left
(fun st (_, (id, _), _) -> let st, _ = get_var st ccmap ("/"^id) in st)
@@ -271,7 +301,8 @@ let program_step p st inputs root_node =
let outputs = List.map
(fun (_, (id, _), _) -> let _, v = get_var st ccmap ("/"^id) in (id, v))
n.ret in
- let st, next_st = extract_next_state true p "" n.body st ccmap in
+
+ let st, next_st = extract_next_state true { p = p; scopes = [""]; c = ccmap } n.body st in
st, outputs, next_st