forked from rems-project/asl-interpreter
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split libASL and isolate Z3 into virtual library (#91)
Z3 links to a native shared library, and so is unsuitable for use via js-of-ocaml. This separates the one use of Z3 in the code (the type-checker's constraint solver) into a separate library which may be stubbed for non-native platforms. This separates libASL into two parts: libASL_ast which is the minimum needed to define the ASL syntax tree, and libASL which contains the rest of the library. libASL should still be used as the public interface of the library. Since libASL re-exports all of libASL_ast, this should not affect the API visible by downstream users. This is required since we need to insert a platform-specific library, libASL_support, which introduces z3 only on native builds. The dependency tree now looks like: libASL_ast <- libASL_support (virtual) <- libASL.
- Loading branch information
1 parent
654a150
commit d3092f9
Showing
13 changed files
with
139 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
; provides platform-specific dependencies | ||
|
||
(library | ||
(name libASL_support) | ||
(public_name asli.libASL-support) | ||
(libraries libASL_ast) | ||
(virtual_modules solver)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
(library | ||
(name libASL_native) | ||
(implements libASL_support) | ||
(libraries z3 libASL_ast)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
(****************************************************************) | ||
(** {3 Z3 support code} *) | ||
(****************************************************************) | ||
|
||
(** Convert ASL expression to Z3 expression. | ||
This only copes with a limited set of operations: ==, +, -, * and DIV. | ||
(It is possible that we will need to extend this list in the future but | ||
it is sufficient for the current ASL specifications.) | ||
The support for DIV is not sound - it is a hack needed to cope with | ||
the way ASL code is written and generally needs a side condition | ||
that the division is exact (no remainder). | ||
ufs is a mutable list of conversions used to handle subexpressions | ||
that cannot be translated. We treat such subexpressions as | ||
uninterpreted functions and add them to the 'ufs' list so that | ||
we can reason that "F(x) == F(x)" without knowing "F". | ||
*) | ||
|
||
module AST = Asl_ast | ||
|
||
let verbose = false | ||
|
||
let rec z3_of_expr (ctx: Z3.context) (ufs: (AST.expr * Z3.Expr.expr) list ref) (x: AST.expr): Z3.Expr.expr = | ||
(match x with | ||
| Expr_Var(v) -> | ||
let intsort = Z3.Arithmetic.Integer.mk_sort ctx in | ||
Z3.Expr.mk_const_s ctx (AST.pprint_ident v) intsort | ||
| Expr_Parens y -> z3_of_expr ctx ufs y | ||
| Expr_LitInt i -> Z3.Arithmetic.Integer.mk_numeral_s ctx i | ||
|
||
(* todo: the following lines involving DIV are not sound *) | ||
| Expr_TApply (FIdent ("mul_int",_), [], [Expr_TApply (FIdent ("fdiv_int",_), [], [a; b]); c]) when b = c -> z3_of_expr ctx ufs a | ||
| Expr_TApply (FIdent ("mul_int",_), [], [a; Expr_TApply (FIdent ("fdiv_int",_), [], [b; c])]) when a = c -> z3_of_expr ctx ufs b | ||
| Expr_TApply (FIdent ("add_int",_), [], [Expr_TApply (FIdent ("fdiv_int",_), [], [a1; b1]); | ||
Expr_TApply (FIdent ("fdiv_int",_), [], [a2; b2])]) | ||
when a1 = a2 && b1 = b2 && b1 = Expr_LitInt "2" | ||
-> z3_of_expr ctx ufs a1 | ||
| Expr_TApply (FIdent ("eq_int",_), [], [a; Expr_TApply (FIdent ("fdiv_int",_), [], [b; c])]) -> | ||
Z3.Boolean.mk_eq ctx | ||
(Z3.Arithmetic.mk_mul ctx [z3_of_expr ctx ufs c; z3_of_expr ctx ufs a]) | ||
(z3_of_expr ctx ufs b) | ||
|
||
| Expr_TApply (FIdent ("add_int",_), [], xs) -> Z3.Arithmetic.mk_add ctx (List.map (z3_of_expr ctx ufs) xs) | ||
| Expr_TApply (FIdent ("sub_int",_), [], xs) -> Z3.Arithmetic.mk_sub ctx (List.map (z3_of_expr ctx ufs) xs) | ||
| Expr_TApply (FIdent ("mul_int",_), [], xs) -> Z3.Arithmetic.mk_mul ctx (List.map (z3_of_expr ctx ufs) xs) | ||
| Expr_TApply (FIdent ("fdiv_int",_), [], [a;b]) -> Z3.Arithmetic.mk_div ctx (z3_of_expr ctx ufs a) (z3_of_expr ctx ufs b) | ||
| Expr_TApply (FIdent ("eq_int",_), [], [a;b]) -> Z3.Boolean.mk_eq ctx (z3_of_expr ctx ufs a) (z3_of_expr ctx ufs b) | ||
| _ -> | ||
if verbose then Printf.printf " Unable to translate %s - using as uninterpreted function\n" (Asl_utils.pp_expr x); | ||
let intsort = Z3.Arithmetic.Integer.mk_sort ctx in | ||
(match List.assoc_opt x !ufs with | ||
| None -> | ||
let uf = Z3.Expr.mk_fresh_const ctx "UNINTERPRETED" intsort in | ||
ufs := (x, uf) :: !ufs; | ||
uf | ||
| Some uf -> | ||
uf | ||
) | ||
) | ||
|
||
(** check that bs => cs *) | ||
let check_constraints (bs: AST.expr list) (cs: AST.expr list): bool = | ||
(* note that we rebuild the Z3 context each time. | ||
* It is possible to share them across all invocations to save | ||
* about 10% of execution time. | ||
*) | ||
let z3_ctx = Z3.mk_context [] in | ||
let solver = Z3.Solver.mk_simple_solver z3_ctx in | ||
let ufs = ref [] in (* uninterpreted function list *) | ||
let bs' = List.map (z3_of_expr z3_ctx ufs) bs in | ||
let cs' = List.map (z3_of_expr z3_ctx ufs) cs in | ||
let p = Z3.Boolean.mk_implies z3_ctx (Z3.Boolean.mk_and z3_ctx bs') (Z3.Boolean.mk_and z3_ctx cs') in | ||
if verbose then Printf.printf " - Checking %s\n" (Z3.Expr.to_string p); | ||
Z3.Solver.add solver [Z3.Boolean.mk_not z3_ctx p]; | ||
let q = Z3.Solver.check solver [] in | ||
if q = SATISFIABLE then Printf.printf "Failed property %s\n" (Z3.Expr.to_string p); | ||
q = UNSATISFIABLE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(****************************************************************) | ||
(** {3 Z3 support code} *) | ||
(****************************************************************) | ||
|
||
(** check that bs => cs *) | ||
val check_constraints : (Asl_ast.expr list) -> (Asl_ast.expr list) -> bool |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
(* AUTO-GENERATED LIFTER FILE *) | ||
|
||
open Offline_utils | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,11 @@ | ||
; AUTO-GENERATED BY OCAML BACKEND | ||
(library | ||
(name offlineASL) | ||
(flags | ||
(:standard -w -27 -cclib -lstdc++)) | ||
(modules offline utils) | ||
(libraries zarith libASL)) | ||
(:standard -w -27 -w -33 -cclib -lstdc++)) | ||
(modules | ||
offline | ||
decode_tests | ||
offline_utils | ||
) | ||
(libraries libASL)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
(test (name test_asl) | ||
(modes exe) | ||
(flags (-cclib -lstdc++)) | ||
(libraries alcotest libASL)) | ||
(libraries alcotest libASL libASL_native)) |