Skip to content

Commit

Permalink
Mcmt loop
Browse files Browse the repository at this point in the history
  • Loading branch information
lmpick committed Aug 9, 2016
1 parent 30c34c1 commit 3cc16fd
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 10 deletions.
21 changes: 12 additions & 9 deletions frontend/abs/simple/interpret_simple.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
(* Interpret simple programs *)
open Simple_ast;;
open Print_simple;;
open Bddapron;;
open Bddapron.Syntax;;
open Apron;;
Expand All @@ -11,7 +12,6 @@ exception Unexpected_expression;;
(* Make a boolean expression out of two boolean expressions
e1 and e2 and a boolean binary operator binop *)
let rec make_bool_expr env cond binop e1 e2 =
printf "%s\n" "make_bool_expr";
let e1' = Expr1.Bool.of_expr (make_expr1 env cond e1) in
let e2' = Expr1.Bool.of_expr (make_expr1 env cond e2) in
Expr1.Bool.to_expr (binop cond e1' e2')
Expand All @@ -34,7 +34,6 @@ make_expr1 env cond = function
(* Arithmetic operators (i.e., And, Sub, Mul, Div) currently use default type (e.g. REAL, INT) and
rounding settings *)
| Add (e1, e2) ->
printf "add: %d of %d\n" (env.Bdd.Env.bddindex) (env.Bdd.Env.bddsize);
let e1' = Expr1.Apron.of_expr (make_expr1 env cond e1) in
let e2' = Expr1.Apron.of_expr (make_expr1 env cond e2) in
Expr1.Apron.to_expr (Expr1.Apron.add cond e1' e2')
Expand All @@ -53,7 +52,6 @@ make_expr1 env cond = function
| Ge (e1, e2) -> make_apron_comp env cond Expr1.Apron.supeq (Sub (e1, e2))
| Gt (e1, e2) -> make_apron_comp env cond Expr1.Apron.sup (Sub (e1, e2))
| Eq (e1, e2) ->
printf "%s\n" "eq";
let e1' = make_expr1 env cond e1 in
let e2' = make_expr1 env cond e2 in
let t1 = Expr1.typ_of_expr e1' in
Expand All @@ -68,10 +66,8 @@ make_expr1 env cond = function
|> Expr1.Bool.to_expr
else Expr1.Bool.to_expr (Expr1.eq cond e1' e2')
| And (e1, e2) ->
printf "and: %d of %d\n" (env.Bdd.Env.bddindex) (env.Bdd.Env.bddsize);
make_bool_expr env cond Expr1.Bool.dand e1 e2
| Or (e1, e2) ->
printf "or: %d of %d\n" (env.Bdd.Env.bddindex) (env.Bdd.Env.bddsize);
make_bool_expr env cond Expr1.Bool.dor e1 e2
| Not e ->
Expr1.Bool.to_expr (Expr1.Bool.dnot cond (Expr1.Bool.of_expr (make_expr1 env cond e)))
Expand Down Expand Up @@ -100,7 +96,11 @@ let rec interpret carry_conditionals man env cond inv ctx = function
| Seq [] -> ctx
| Branch es ->
let ctx's = List.map (interpret carry_conditionals man env cond inv ctx) es in
List.fold_left (Domain1.join man) (Domain1.bottom man env) ctx's
let res = List.fold_left (Domain1.join man) (Domain1.bottom man env) ctx's in
(*
printf "branch: %d of %d\n" (env.Bdd.Env.bddindex) (env.Bdd.Env.bddsize);
printf "env: %a@." Env.print env;*)
res
| Cond (e1, e2, e3) ->
let e1' = Expr1.Bool.of_expr (make_expr1 env cond e1)
|> Domain1.meet_condition man cond ctx in
Expand Down Expand Up @@ -153,7 +153,10 @@ let rec interpret carry_conditionals man env cond inv ctx = function
let ctx' = Domain1.change_environment man ctx env' |> Domain1.meet man inv' in
let res = interpret carry_conditionals man env' cond inv' ctx' e2 in
Domain1.change_environment man res env
| other -> printf "%s\n" "other"; Domain1.meet_condition man cond inv (Expr1.Bool.of_expr (make_expr1 env cond other));;
| other ->
let condition = Expr1.Bool.of_expr (make_expr1 env cond other) in
let condition' = Domain1.meet_condition man (Cond.copy cond) ctx condition in
Domain1.meet man inv condition';;

let initialize apron ds invs =
let rec generate pairs constraints env = function
Expand All @@ -167,12 +170,12 @@ let initialize apron ds invs =
| (Constraint_decl (decl, cond))::ds -> generate pairs (cond::constraints) env (decl::ds) in
let cudd = Cudd.Man.make_v () in (* in the future, may need to make cudd parameterizable *)
Cudd.Man.set_gc 10000
(begin fun () -> printf "@.CUDD GC@." end)
(begin fun () -> Cudd.Man.print_info cudd; printf "@.CUDD GC@." end)
(begin fun () -> printf "@.CUDD REORDER@." end);
let (pairs, constraints, env) = generate [] [] (Env.make ~symbol:Env.string_symbol ~bddsize:(100) cudd) ds in
let env = Env.add_vars env pairs in (* create an environment with declared variables *)
let cond = Cond.make Env.string_symbol cudd in
let man = Domain1.man_of_mtbdd (Domain1.make_mtbdd apron) in (* to do: make this a parameter *)
let man = Domain1.man_of_bdd (Domain1.make_bdd apron) in
let abs = Domain1.top man env in
let constraints = List.map (fun x -> Expr1.Bool.of_expr (make_expr1 env cond x)) (constraints @ invs) in
(man, env, cond, List.fold_left (Domain1.meet_condition man cond) abs constraints);;
Expand Down
2 changes: 1 addition & 1 deletion frontend/abs/simple/print_simple.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ let rec string_of_simple = function
| False -> "false"
| Seq (e::es) -> (string_of_simple e)^"; "^(string_of_simple (Seq es))
| Seq [] -> ""
| Branch [e1; e2] -> "("^(string_of_simple e1)^")\n||\n("^(string_of_simple e2)^")"
| Branch (e::es) -> "("^(string_of_simple e)^")\n||\n"^(string_of_simple (Branch es))
| Branch [] -> ""
| Local (decl, e) ->
match decl with
| Nat_decl str -> "(let "^str^" : nat in "^(string_of_simple e)^")"
Expand Down
70 changes: 70 additions & 0 deletions frontend/abs_mcmt.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
open Abs.Mcmt_lexer;;
open Abs.Mcmt_to_simple_ast;;
open Abs.Print_simple;;
open Abs.Mcmt_simple_ast;;
open Abs.Interpret_simple;;
open Abs;;
open Bddapron;;
open Format;;

exception Malformed_mcmt_prog;;

let eval_step man env inv cond ts ctx =
let string_from_decl = function
| Simple_ast.Nat_decl str -> str
| Simple_ast.Int_decl str -> str
| Simple_ast.Real_decl str -> str
| Simple_ast.Bool_decl str -> str
| Simple_ast.Enum_decl (str, _) -> str
| _ -> raise Malformed_mcmt_prog in
let current = List.map string_from_decl ts.current_sv_decls in
let next = List.map string_from_decl ts.next_sv_decls in
printf "ctx: %a@." (Domain1.print man) ctx;
let next_exprs = List.map (Expr1.var env cond) next in
let assigned = Domain1.assign_lexpr man cond ctx current next_exprs None in
let forget = Domain1.forget_list man assigned next in
Domain1.meet man inv forget;;

let rec eval_mcmt man env cond inv ctx ts lim cnt =
let ctx' = interpret false man env cond inv ctx ts.trans |> eval_step man env inv cond ts |> Domain1.join man ctx in
printf "ctx': %a@." (Domain1.print man) ctx';
(*
printf "index: %d@." (env.Bdd.Env.bddindex0);
printf "env: %a@." (Env.print) env;;*)
if (Domain1.is_eq man ctx ctx')
then ctx
else if cnt = 0 then
let widened = Domain1.widening man ctx ctx' in
let narrowed = eval_step man env inv cond ts (interpret true man env cond inv widened ts.trans) |> Domain1.join man ctx in
eval_mcmt man env cond inv narrowed ts lim lim
else eval_mcmt man env cond inv ctx' ts lim (cnt - 1);;

let eval_mcmt_prog ts =
let decls = ts.decls @ ts.current_sv_decls @ ts.next_sv_decls in
let invs = ts.invs in
let (man, env, cond, ctx) = initialize (Polka.manager_alloc_strict()) decls invs in
let init = interpret true man env cond ctx ctx ts.init in
printf "initial state: %a@." (Domain1.print man) init;
let res = eval_mcmt man env cond ctx init ts 5 5 in
printf "res: %a@." (Domain1.print man) res;;

let print_transition_system ts =
printf "Transition system: %s\n" ts.name;
List.iter (fun x -> printf "Invariant: %s\n" (string_of_simple x)) ts.invs;
printf "Initial:%s\n" (string_of_simple ts.init);
printf "Transition:%s\n" (string_of_simple ts.trans);
eval_mcmt_prog ts;;

let create_channel_in = function
| Some filename -> open_in filename
| None -> stdin;;

let _ =
let input_file = ref None in
(let open Arg in
Arg.parse [] (fun f ->
input_file := Some f) "");
create_channel_in !input_file
|> parse
|> fun x -> printf "%s\n" "parsed"; mcmt_to_ts x
|> List.iter print_transition_system;;

0 comments on commit 3cc16fd

Please sign in to comment.