|
|
@ -18,6 +18,12 @@ end
|
|
|
|
module rec T : sig
|
|
|
|
module rec T : sig
|
|
|
|
type qset = Qset.M(T).t [@@deriving compare, equal, hash, sexp]
|
|
|
|
type qset = Qset.M(T).t [@@deriving compare, equal, hash, sexp]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type op1 =
|
|
|
|
|
|
|
|
(* conversion *)
|
|
|
|
|
|
|
|
| Extract of {unsigned: bool; bits: int}
|
|
|
|
|
|
|
|
| Convert of {unsigned: bool; dst: Typ.t; src: Typ.t}
|
|
|
|
|
|
|
|
[@@deriving compare, equal, hash, sexp]
|
|
|
|
|
|
|
|
|
|
|
|
type t =
|
|
|
|
type t =
|
|
|
|
(* nary: arithmetic, numeric and pointer *)
|
|
|
|
(* nary: arithmetic, numeric and pointer *)
|
|
|
|
| Add of qset
|
|
|
|
| Add of qset
|
|
|
@ -30,7 +36,8 @@ module rec T : sig
|
|
|
|
| Var of {id: int; name: string}
|
|
|
|
| Var of {id: int; name: string}
|
|
|
|
| Nondet of {msg: string}
|
|
|
|
| Nondet of {msg: string}
|
|
|
|
| Label of {parent: string; name: string}
|
|
|
|
| Label of {parent: string; name: string}
|
|
|
|
(* curried application *)
|
|
|
|
(* application *)
|
|
|
|
|
|
|
|
| Ap1 of op1 * t
|
|
|
|
| App of {op: t; arg: t}
|
|
|
|
| App of {op: t; arg: t}
|
|
|
|
(* binary: comparison *)
|
|
|
|
(* binary: comparison *)
|
|
|
|
| Eq
|
|
|
|
| Eq
|
|
|
@ -56,9 +63,6 @@ module rec T : sig
|
|
|
|
| Select
|
|
|
|
| Select
|
|
|
|
| Update
|
|
|
|
| Update
|
|
|
|
| Struct_rec of {elts: t vector} (** NOTE: may be cyclic *)
|
|
|
|
| Struct_rec of {elts: t vector} (** NOTE: may be cyclic *)
|
|
|
|
(* unary: conversion *)
|
|
|
|
|
|
|
|
| Extract of {unsigned: bool; bits: int}
|
|
|
|
|
|
|
|
| Convert of {unsigned: bool; dst: Typ.t; src: Typ.t}
|
|
|
|
|
|
|
|
(* numeric constants *)
|
|
|
|
(* numeric constants *)
|
|
|
|
| Integer of {data: Z.t}
|
|
|
|
| Integer of {data: Z.t}
|
|
|
|
| Float of {data: string}
|
|
|
|
| Float of {data: string}
|
|
|
@ -79,6 +83,11 @@ end
|
|
|
|
and T0 : sig
|
|
|
|
and T0 : sig
|
|
|
|
type qset = Qset.M(T).t [@@deriving compare, equal, hash, sexp]
|
|
|
|
type qset = Qset.M(T).t [@@deriving compare, equal, hash, sexp]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type op1 =
|
|
|
|
|
|
|
|
| Extract of {unsigned: bool; bits: int}
|
|
|
|
|
|
|
|
| Convert of {unsigned: bool; dst: Typ.t; src: Typ.t}
|
|
|
|
|
|
|
|
[@@deriving compare, equal, hash, sexp]
|
|
|
|
|
|
|
|
|
|
|
|
type t =
|
|
|
|
type t =
|
|
|
|
| Add of qset
|
|
|
|
| Add of qset
|
|
|
|
| Mul of qset
|
|
|
|
| Mul of qset
|
|
|
@ -88,6 +97,7 @@ and T0 : sig
|
|
|
|
| Var of {id: int; name: string}
|
|
|
|
| Var of {id: int; name: string}
|
|
|
|
| Nondet of {msg: string}
|
|
|
|
| Nondet of {msg: string}
|
|
|
|
| Label of {parent: string; name: string}
|
|
|
|
| Label of {parent: string; name: string}
|
|
|
|
|
|
|
|
| Ap1 of op1 * t
|
|
|
|
| App of {op: t; arg: t}
|
|
|
|
| App of {op: t; arg: t}
|
|
|
|
| Eq
|
|
|
|
| Eq
|
|
|
|
| Dq
|
|
|
|
| Dq
|
|
|
@ -108,14 +118,17 @@ and T0 : sig
|
|
|
|
| Select
|
|
|
|
| Select
|
|
|
|
| Update
|
|
|
|
| Update
|
|
|
|
| Struct_rec of {elts: t vector}
|
|
|
|
| Struct_rec of {elts: t vector}
|
|
|
|
| Extract of {unsigned: bool; bits: int}
|
|
|
|
|
|
|
|
| Convert of {unsigned: bool; dst: Typ.t; src: Typ.t}
|
|
|
|
|
|
|
|
| Integer of {data: Z.t}
|
|
|
|
| Integer of {data: Z.t}
|
|
|
|
| Float of {data: string}
|
|
|
|
| Float of {data: string}
|
|
|
|
[@@deriving compare, equal, hash, sexp]
|
|
|
|
[@@deriving compare, equal, hash, sexp]
|
|
|
|
end = struct
|
|
|
|
end = struct
|
|
|
|
type qset = Qset.M(T).t [@@deriving compare, equal, hash, sexp]
|
|
|
|
type qset = Qset.M(T).t [@@deriving compare, equal, hash, sexp]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type op1 =
|
|
|
|
|
|
|
|
| Extract of {unsigned: bool; bits: int}
|
|
|
|
|
|
|
|
| Convert of {unsigned: bool; dst: Typ.t; src: Typ.t}
|
|
|
|
|
|
|
|
[@@deriving compare, equal, hash, sexp]
|
|
|
|
|
|
|
|
|
|
|
|
type t =
|
|
|
|
type t =
|
|
|
|
| Add of qset
|
|
|
|
| Add of qset
|
|
|
|
| Mul of qset
|
|
|
|
| Mul of qset
|
|
|
@ -125,6 +138,7 @@ end = struct
|
|
|
|
| Var of {id: int; name: string}
|
|
|
|
| Var of {id: int; name: string}
|
|
|
|
| Nondet of {msg: string}
|
|
|
|
| Nondet of {msg: string}
|
|
|
|
| Label of {parent: string; name: string}
|
|
|
|
| Label of {parent: string; name: string}
|
|
|
|
|
|
|
|
| Ap1 of op1 * t
|
|
|
|
| App of {op: t; arg: t}
|
|
|
|
| App of {op: t; arg: t}
|
|
|
|
| Eq
|
|
|
|
| Eq
|
|
|
|
| Dq
|
|
|
|
| Dq
|
|
|
@ -145,8 +159,6 @@ end = struct
|
|
|
|
| Select
|
|
|
|
| Select
|
|
|
|
| Update
|
|
|
|
| Update
|
|
|
|
| Struct_rec of {elts: t vector}
|
|
|
|
| Struct_rec of {elts: t vector}
|
|
|
|
| Extract of {unsigned: bool; bits: int}
|
|
|
|
|
|
|
|
| Convert of {unsigned: bool; dst: Typ.t; src: Typ.t}
|
|
|
|
|
|
|
|
| Integer of {data: Z.t}
|
|
|
|
| Integer of {data: Z.t}
|
|
|
|
| Float of {data: string}
|
|
|
|
| Float of {data: string}
|
|
|
|
[@@deriving compare, equal, hash, sexp]
|
|
|
|
[@@deriving compare, equal, hash, sexp]
|
|
|
@ -265,13 +277,14 @@ let rec pp ?is_x fs term =
|
|
|
|
| op, [x; y] -> pf "(%a@ %a %a)" pp x pp op pp y
|
|
|
|
| op, [x; y] -> pf "(%a@ %a %a)" pp x pp op pp y
|
|
|
|
| _ -> pf "(%a@ %a)" pp op pp arg )
|
|
|
|
| _ -> pf "(%a@ %a)" pp op pp arg )
|
|
|
|
| Struct_rec {elts} -> pf "{|%a|}" (Vector.pp ",@ " pp) elts
|
|
|
|
| Struct_rec {elts} -> pf "{|%a|}" (Vector.pp ",@ " pp) elts
|
|
|
|
| Extract {unsigned; bits} ->
|
|
|
|
| Ap1 (Extract {unsigned; bits}, arg) ->
|
|
|
|
pf "(%s%i)" (if unsigned then "u" else "i") bits
|
|
|
|
pf "(%s%i)@ %a" (if unsigned then "u" else "i") bits pp arg
|
|
|
|
| Convert {unsigned= true; dst; src= Integer {bits}} ->
|
|
|
|
| Ap1 (Convert {dst; unsigned= true; src= Integer {bits}}, arg) ->
|
|
|
|
pf "(%a)(u%i)" Typ.pp dst bits
|
|
|
|
pf "((%a)(u%i)@ %a)" Typ.pp dst bits pp arg
|
|
|
|
| Convert {unsigned= true; dst= Integer {bits}; src} ->
|
|
|
|
| Ap1 (Convert {unsigned= true; dst= Integer {bits}; src}, arg) ->
|
|
|
|
pf "(u%i)(%a)" bits Typ.pp src
|
|
|
|
pf "((u%i)(%a)@ %a)" bits Typ.pp src pp arg
|
|
|
|
| Convert {dst; src} -> pf "(%a)(%a)" Typ.pp dst Typ.pp src
|
|
|
|
| Ap1 (Convert {dst; src}, arg) ->
|
|
|
|
|
|
|
|
pf "((%a)(%a)@ %a)" Typ.pp dst Typ.pp src pp arg
|
|
|
|
in
|
|
|
|
in
|
|
|
|
fix_flip pp_ (fun _ _ -> ()) fs term
|
|
|
|
fix_flip pp_ (fun _ _ -> ()) fs term
|
|
|
|
|
|
|
|
|
|
|
@ -359,10 +372,8 @@ let invariant ?(partial = false) e =
|
|
|
|
| App _ -> fail "uncurry cannot return App" ()
|
|
|
|
| App _ -> fail "uncurry cannot return App" ()
|
|
|
|
| Integer _ -> assert_arity 0
|
|
|
|
| Integer _ -> assert_arity 0
|
|
|
|
| Var _ | Nondet _ | Label _ | Float _ -> assert_arity 0
|
|
|
|
| Var _ | Nondet _ | Label _ | Float _ -> assert_arity 0
|
|
|
|
| Extract _ -> assert_arity 1
|
|
|
|
| Ap1 (Extract _, _) -> assert true
|
|
|
|
| Convert {dst; src} ->
|
|
|
|
| Ap1 (Convert {dst; src}, _) -> assert (Typ.convertible src dst)
|
|
|
|
assert_arity 1 ;
|
|
|
|
|
|
|
|
assert (Typ.convertible src dst)
|
|
|
|
|
|
|
|
| Add _ -> assert_polynomial e |> Fn.id
|
|
|
|
| Add _ -> assert_polynomial e |> Fn.id
|
|
|
|
| Mul _ -> assert_monomial e |> Fn.id
|
|
|
|
| Mul _ -> assert_monomial e |> Fn.id
|
|
|
|
| Eq | Dq | Lt | Le | Div | Rem | And | Or | Xor | Shl | Lshr | Ashr ->
|
|
|
|
| Eq | Dq | Lt | Le | Div | Rem | And | Or | Xor | Shl | Lshr | Ashr ->
|
|
|
@ -499,6 +510,7 @@ let fold_terms e ~init ~f =
|
|
|
|
let fold_terms_ fold_terms_ e z =
|
|
|
|
let fold_terms_ fold_terms_ e z =
|
|
|
|
let z =
|
|
|
|
let z =
|
|
|
|
match e with
|
|
|
|
match e with
|
|
|
|
|
|
|
|
| Ap1 (_, x) -> fold_terms_ x z
|
|
|
|
| App {op= x; arg= y}
|
|
|
|
| App {op= x; arg= y}
|
|
|
|
|Splat {byt= x; siz= y}
|
|
|
|
|Splat {byt= x; siz= y}
|
|
|
|
|Memory {siz= x; arr= y} ->
|
|
|
|
|Memory {siz= x; arr= y} ->
|
|
|
@ -539,7 +551,7 @@ let float data = Float {data} |> check invariant
|
|
|
|
let simp_extract ~unsigned bits arg =
|
|
|
|
let simp_extract ~unsigned bits arg =
|
|
|
|
match arg with
|
|
|
|
match arg with
|
|
|
|
| Integer {data} -> integer (Z.extract ~unsigned bits data)
|
|
|
|
| Integer {data} -> integer (Z.extract ~unsigned bits data)
|
|
|
|
| _ -> App {op= Extract {unsigned; bits}; arg}
|
|
|
|
| _ -> Ap1 (Extract {unsigned; bits}, arg)
|
|
|
|
|
|
|
|
|
|
|
|
let simp_convert ~unsigned dst src arg =
|
|
|
|
let simp_convert ~unsigned dst src arg =
|
|
|
|
if (not unsigned) && Typ.castable dst src then arg
|
|
|
|
if (not unsigned) && Typ.castable dst src then arg
|
|
|
@ -547,7 +559,7 @@ let simp_convert ~unsigned dst src arg =
|
|
|
|
match (dst, src, arg) with
|
|
|
|
match (dst, src, arg) with
|
|
|
|
| Integer {bits= m}, Integer {bits= n}, Integer {data} ->
|
|
|
|
| Integer {bits= m}, Integer {bits= n}, Integer {data} ->
|
|
|
|
integer (Z.extract ~unsigned (min m n) data)
|
|
|
|
integer (Z.extract ~unsigned (min m n) data)
|
|
|
|
| _ -> App {op= Convert {unsigned; dst; src}; arg}
|
|
|
|
| _ -> Ap1 (Convert {unsigned; dst; src}, arg)
|
|
|
|
|
|
|
|
|
|
|
|
let simp_lt x y =
|
|
|
|
let simp_lt x y =
|
|
|
|
match (x, y) with
|
|
|
|
match (x, y) with
|
|
|
@ -757,7 +769,7 @@ let rec simp_or x y =
|
|
|
|
|
|
|
|
|
|
|
|
let rec is_boolean = function
|
|
|
|
let rec is_boolean = function
|
|
|
|
| App {op= App {op= Eq | Dq | Lt | Le}}
|
|
|
|
| App {op= App {op= Eq | Dq | Lt | Le}}
|
|
|
|
|App {op= Convert {dst= Integer {bits= 1}}} ->
|
|
|
|
|Ap1 ((Extract {bits= 1} | Convert {dst= Integer {bits= 1}}), _) ->
|
|
|
|
true
|
|
|
|
true
|
|
|
|
| App
|
|
|
|
| App
|
|
|
|
{ op= App {op= Div | Rem | And | Or | Xor | Shl | Lshr | Ashr; arg= x}
|
|
|
|
{ op= App {op= Div | Rem | And | Or | Xor | Shl | Lshr | Ashr; arg= x}
|
|
|
@ -865,6 +877,7 @@ let simp_ashr x y =
|
|
|
|
|
|
|
|
|
|
|
|
let iter e ~f =
|
|
|
|
let iter e ~f =
|
|
|
|
match e with
|
|
|
|
match e with
|
|
|
|
|
|
|
|
| Ap1 (_, x) -> f x
|
|
|
|
| App {op= x; arg= y} | Splat {byt= x; siz= y} | Memory {siz= x; arr= y}
|
|
|
|
| App {op= x; arg= y} | Splat {byt= x; siz= y} | Memory {siz= x; arr= y}
|
|
|
|
->
|
|
|
|
->
|
|
|
|
f x ; f y
|
|
|
|
f x ; f y
|
|
|
@ -874,6 +887,7 @@ let iter e ~f =
|
|
|
|
|
|
|
|
|
|
|
|
let fold e ~init:s ~f =
|
|
|
|
let fold e ~init:s ~f =
|
|
|
|
match e with
|
|
|
|
match e with
|
|
|
|
|
|
|
|
| Ap1 (_, x) -> f x s
|
|
|
|
| App {op= x; arg= y} | Splat {byt= x; siz= y} | Memory {siz= x; arr= y}
|
|
|
|
| App {op= x; arg= y} | Splat {byt= x; siz= y} | Memory {siz= x; arr= y}
|
|
|
|
->
|
|
|
|
->
|
|
|
|
f y (f x s)
|
|
|
|
f y (f x s)
|
|
|
@ -888,6 +902,12 @@ let is_subterm ~sub ~sup =
|
|
|
|
iter_terms sup ~f:(fun e -> if equal sub e then return true) ;
|
|
|
|
iter_terms sup ~f:(fun e -> if equal sub e then return true) ;
|
|
|
|
false
|
|
|
|
false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let norm1 op x =
|
|
|
|
|
|
|
|
( match op with
|
|
|
|
|
|
|
|
| Extract {unsigned; bits} -> simp_extract ~unsigned bits x
|
|
|
|
|
|
|
|
| Convert {unsigned; dst; src} -> simp_convert ~unsigned dst src x )
|
|
|
|
|
|
|
|
|> check invariant
|
|
|
|
|
|
|
|
|
|
|
|
let app1 ?(partial = false) op arg =
|
|
|
|
let app1 ?(partial = false) op arg =
|
|
|
|
( match (op, arg) with
|
|
|
|
( match (op, arg) with
|
|
|
|
| App {op= Eq; arg= x}, y -> simp_eq x y
|
|
|
|
| App {op= Eq; arg= x}, y -> simp_eq x y
|
|
|
@ -905,8 +925,6 @@ let app1 ?(partial = false) op arg =
|
|
|
|
| App {op= Lshr; arg= x}, y -> simp_lshr x y
|
|
|
|
| App {op= Lshr; arg= x}, y -> simp_lshr x y
|
|
|
|
| App {op= Ashr; arg= x}, y -> simp_ashr x y
|
|
|
|
| App {op= Ashr; arg= x}, y -> simp_ashr x y
|
|
|
|
| App {op= App {op= Conditional; arg= x}; arg= y}, z -> simp_cond x y z
|
|
|
|
| App {op= App {op= Conditional; arg= x}; arg= y}, z -> simp_cond x y z
|
|
|
|
| Extract {unsigned; bits}, x -> simp_extract ~unsigned bits x
|
|
|
|
|
|
|
|
| Convert {unsigned; dst; src}, x -> simp_convert ~unsigned dst src x
|
|
|
|
|
|
|
|
| _ -> App {op; arg} )
|
|
|
|
| _ -> App {op; arg} )
|
|
|
|
|> check (invariant ~partial)
|
|
|
|
|> check (invariant ~partial)
|
|
|
|
|> check (fun e ->
|
|
|
|
|> check (fun e ->
|
|
|
@ -1006,10 +1024,10 @@ let struct_rec key =
|
|
|
|
Struct_rec {elts}
|
|
|
|
Struct_rec {elts}
|
|
|
|
|
|
|
|
|
|
|
|
let extract ?(unsigned = false) ~bits term =
|
|
|
|
let extract ?(unsigned = false) ~bits term =
|
|
|
|
app1 (Extract {unsigned; bits}) term
|
|
|
|
norm1 (Extract {unsigned; bits}) term
|
|
|
|
|
|
|
|
|
|
|
|
let convert ?(unsigned = false) ~dst ~src term =
|
|
|
|
let convert ?(unsigned = false) ~dst ~src term =
|
|
|
|
app1 (Convert {unsigned; dst; src}) term
|
|
|
|
norm1 (Convert {unsigned; dst; src}) term
|
|
|
|
|
|
|
|
|
|
|
|
let size_of t =
|
|
|
|
let size_of t =
|
|
|
|
Option.bind (Typ.prim_bit_size_of t) ~f:(fun n ->
|
|
|
|
Option.bind (Typ.prim_bit_size_of t) ~f:(fun n ->
|
|
|
@ -1073,6 +1091,10 @@ let rec of_exp (e : Exp.t) =
|
|
|
|
let map e ~f =
|
|
|
|
let map e ~f =
|
|
|
|
let map_ : (t -> t) -> t -> t =
|
|
|
|
let map_ : (t -> t) -> t -> t =
|
|
|
|
fun map_ e ->
|
|
|
|
fun map_ e ->
|
|
|
|
|
|
|
|
let map1 op ~f x =
|
|
|
|
|
|
|
|
let x' = f x in
|
|
|
|
|
|
|
|
if x' == x then e else norm1 op x'
|
|
|
|
|
|
|
|
in
|
|
|
|
let map_bin mk ~f x y =
|
|
|
|
let map_bin mk ~f x y =
|
|
|
|
let x' = f x in
|
|
|
|
let x' = f x in
|
|
|
|
let y' = f y in
|
|
|
|
let y' = f y in
|
|
|
@ -1094,6 +1116,7 @@ let map e ~f =
|
|
|
|
| Memory {siz; arr} -> map_bin simp_memory ~f siz arr
|
|
|
|
| Memory {siz; arr} -> map_bin simp_memory ~f siz arr
|
|
|
|
| Concat {args} -> map_vector simp_concat ~f args
|
|
|
|
| Concat {args} -> map_vector simp_concat ~f args
|
|
|
|
| Struct_rec {elts= args} -> Struct_rec {elts= Vector.map args ~f:map_}
|
|
|
|
| Struct_rec {elts= args} -> Struct_rec {elts= Vector.map args ~f:map_}
|
|
|
|
|
|
|
|
| Ap1 (op, x) -> map1 op ~f x
|
|
|
|
| _ -> e
|
|
|
|
| _ -> e
|
|
|
|
in
|
|
|
|
in
|
|
|
|
fix map_ (fun e -> e) e
|
|
|
|
fix map_ (fun e -> e) e
|
|
|
@ -1115,6 +1138,7 @@ let rec is_constant e =
|
|
|
|
let is_constant_bin x y = is_constant x && is_constant y in
|
|
|
|
let is_constant_bin x y = is_constant x && is_constant y in
|
|
|
|
match e with
|
|
|
|
match e with
|
|
|
|
| Var _ | Nondet _ -> false
|
|
|
|
| Var _ | Nondet _ -> false
|
|
|
|
|
|
|
|
| Ap1 (_, x) -> is_constant x
|
|
|
|
| App {op= x; arg= y} | Splat {byt= x; siz= y} | Memory {siz= x; arr= y}
|
|
|
|
| App {op= x; arg= y} | Splat {byt= x; siz= y} | Memory {siz= x; arr= y}
|
|
|
|
->
|
|
|
|
->
|
|
|
|
is_constant_bin x y
|
|
|
|
is_constant_bin x y
|
|
|
@ -1127,7 +1151,7 @@ let rec is_constant e =
|
|
|
|
let classify = function
|
|
|
|
let classify = function
|
|
|
|
| Add _ | Mul _ -> `Interpreted
|
|
|
|
| Add _ | Mul _ -> `Interpreted
|
|
|
|
| App {op= Eq | Dq | App {op= Eq | Dq}} -> `Simplified
|
|
|
|
| App {op= Eq | Dq | App {op= Eq | Dq}} -> `Simplified
|
|
|
|
| App _ -> `Uninterpreted
|
|
|
|
| Ap1 _ | App _ -> `Uninterpreted
|
|
|
|
| _ -> `Atomic
|
|
|
|
| _ -> `Atomic
|
|
|
|
|
|
|
|
|
|
|
|
let solve e f =
|
|
|
|
let solve e f =
|
|
|
|