mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 11:15:43 -05:00
feat: add AST for LRA
This commit is contained in:
parent
216cbe762f
commit
943efad206
5 changed files with 97 additions and 5 deletions
|
|
@ -4,6 +4,15 @@ module Fmt = CCFormat
|
||||||
|
|
||||||
module CC_view = Sidekick_core.CC_view
|
module CC_view = Sidekick_core.CC_view
|
||||||
|
|
||||||
|
type lra_pred = Sidekick_lra.pred = Lt | Leq | Eq | Neq | Geq | Gt
|
||||||
|
type lra_op = Sidekick_lra.op = Plus | Minus
|
||||||
|
|
||||||
|
type 'a lra_view = 'a Sidekick_lra.lra_view =
|
||||||
|
| LRA_pred of lra_pred * 'a * 'a
|
||||||
|
| LRA_op of lra_op * 'a * 'a
|
||||||
|
| LRA_const of Q.t
|
||||||
|
| LRA_other of 'a
|
||||||
|
|
||||||
(* main term cell. *)
|
(* main term cell. *)
|
||||||
type term = {
|
type term = {
|
||||||
mutable term_id: int; (* unique ID *)
|
mutable term_id: int; (* unique ID *)
|
||||||
|
|
@ -18,6 +27,7 @@ and 'a term_view =
|
||||||
| Eq of 'a * 'a
|
| Eq of 'a * 'a
|
||||||
| Not of 'a
|
| Not of 'a
|
||||||
| Ite of 'a * 'a * 'a
|
| Ite of 'a * 'a * 'a
|
||||||
|
| LRA of 'a lra_view
|
||||||
|
|
||||||
and fun_ = {
|
and fun_ = {
|
||||||
fun_id: ID.t;
|
fun_id: ID.t;
|
||||||
|
|
@ -193,6 +203,20 @@ let rec pp_ty out t = match t.ty_view with
|
||||||
| Ty_atomic {def=Ty_data d; args;_} ->
|
| Ty_atomic {def=Ty_data d; args;_} ->
|
||||||
Fmt.fprintf out "(@[%a@ %a@])" ID.pp d.data.data_id (Util.pp_list pp_ty) args
|
Fmt.fprintf out "(@[%a@ %a@])" ID.pp d.data.data_id (Util.pp_list pp_ty) args
|
||||||
|
|
||||||
|
let string_of_lra_pred = function
|
||||||
|
| Lt -> "<"
|
||||||
|
| Leq -> "<="
|
||||||
|
| Neq -> "!="
|
||||||
|
| Eq -> "="
|
||||||
|
| Gt-> ">"
|
||||||
|
| Geq -> ">="
|
||||||
|
let pp_pred out p = Fmt.string out (string_of_lra_pred p)
|
||||||
|
|
||||||
|
let string_of_lra_op = function
|
||||||
|
| Plus -> "+"
|
||||||
|
| Minus -> "-"
|
||||||
|
let pp_lra_op out p = Fmt.string out (string_of_lra_op p)
|
||||||
|
|
||||||
let pp_term_view_gen ~pp_id ~pp_t out = function
|
let pp_term_view_gen ~pp_id ~pp_t out = function
|
||||||
| Bool true -> Fmt.string out "true"
|
| Bool true -> Fmt.string out "true"
|
||||||
| Bool false -> Fmt.string out "false"
|
| Bool false -> Fmt.string out "false"
|
||||||
|
|
@ -204,6 +228,15 @@ let pp_term_view_gen ~pp_id ~pp_t out = function
|
||||||
| Eq (a,b) -> Fmt.fprintf out "(@[<hv>=@ %a@ %a@])" pp_t a pp_t b
|
| Eq (a,b) -> Fmt.fprintf out "(@[<hv>=@ %a@ %a@])" pp_t a pp_t b
|
||||||
| Not u -> Fmt.fprintf out "(@[not@ %a@])" pp_t u
|
| Not u -> Fmt.fprintf out "(@[not@ %a@])" pp_t u
|
||||||
| Ite (a,b,c) -> Fmt.fprintf out "(@[ite@ %a@ %a@ %a@])" pp_t a pp_t b pp_t c
|
| Ite (a,b,c) -> Fmt.fprintf out "(@[ite@ %a@ %a@ %a@])" pp_t a pp_t b pp_t c
|
||||||
|
| LRA l ->
|
||||||
|
begin match l with
|
||||||
|
| LRA_pred (p, a, b) ->
|
||||||
|
Fmt.fprintf out "(@[%s@ %a@ %a@])" (string_of_lra_pred p) pp_t a pp_t b
|
||||||
|
| LRA_op (p, a, b) ->
|
||||||
|
Fmt.fprintf out "(@[%s@ %a@ %a@])" (string_of_lra_op p) pp_t a pp_t b
|
||||||
|
| LRA_const q -> Q.pp_print out q
|
||||||
|
| LRA_other x -> pp_t out x
|
||||||
|
end
|
||||||
|
|
||||||
let pp_term_top ~ids out t =
|
let pp_term_top ~ids out t =
|
||||||
let rec pp out t =
|
let rec pp out t =
|
||||||
|
|
@ -499,6 +532,7 @@ module Term_cell : sig
|
||||||
| Eq of 'a * 'a
|
| Eq of 'a * 'a
|
||||||
| Not of 'a
|
| Not of 'a
|
||||||
| Ite of 'a * 'a * 'a
|
| Ite of 'a * 'a * 'a
|
||||||
|
| LRA of 'a lra_view
|
||||||
|
|
||||||
type t = term view
|
type t = term view
|
||||||
|
|
||||||
|
|
@ -512,6 +546,7 @@ module Term_cell : sig
|
||||||
val eq : term -> term -> t
|
val eq : term -> term -> t
|
||||||
val not_ : term -> t
|
val not_ : term -> t
|
||||||
val ite : term -> term -> term -> t
|
val ite : term -> term -> term -> t
|
||||||
|
val lra : term lra_view -> t
|
||||||
|
|
||||||
val ty : t -> Ty.t
|
val ty : t -> Ty.t
|
||||||
(** Compute the type of this term cell. Not totally free *)
|
(** Compute the type of this term cell. Not totally free *)
|
||||||
|
|
@ -540,6 +575,7 @@ end = struct
|
||||||
| Eq of 'a * 'a
|
| Eq of 'a * 'a
|
||||||
| Not of 'a
|
| Not of 'a
|
||||||
| Ite of 'a * 'a * 'a
|
| Ite of 'a * 'a * 'a
|
||||||
|
| LRA of 'a lra_view
|
||||||
|
|
||||||
type t = term view
|
type t = term view
|
||||||
|
|
||||||
|
|
@ -561,6 +597,15 @@ end = struct
|
||||||
| Eq (a,b) -> Hash.combine3 12 (sub_hash a) (sub_hash b)
|
| Eq (a,b) -> Hash.combine3 12 (sub_hash a) (sub_hash b)
|
||||||
| Not u -> Hash.combine2 70 (sub_hash u)
|
| Not u -> Hash.combine2 70 (sub_hash u)
|
||||||
| Ite (a,b,c) -> Hash.combine4 80 (sub_hash a)(sub_hash b)(sub_hash c)
|
| Ite (a,b,c) -> Hash.combine4 80 (sub_hash a)(sub_hash b)(sub_hash c)
|
||||||
|
| LRA l ->
|
||||||
|
begin match l with
|
||||||
|
| LRA_pred (p, a, b) ->
|
||||||
|
Hash.combine4 81 (Hash.poly p) (sub_hash a) (sub_hash b)
|
||||||
|
| LRA_op (p, a, b) ->
|
||||||
|
Hash.combine4 82 (Hash.poly p) (sub_hash a) (sub_hash b)
|
||||||
|
| LRA_const q -> Hash.combine2 83 (Hash.string @@ Q.to_string q)
|
||||||
|
| LRA_other x -> sub_hash x
|
||||||
|
end
|
||||||
|
|
||||||
(* equality that relies on physical equality of subterms *)
|
(* equality that relies on physical equality of subterms *)
|
||||||
let equal (a:A.t view) b : bool = match a, b with
|
let equal (a:A.t view) b : bool = match a, b with
|
||||||
|
|
@ -571,7 +616,17 @@ end = struct
|
||||||
| Not a, Not b -> sub_eq a b
|
| Not a, Not b -> sub_eq a b
|
||||||
| Ite (a1,b1,c1), Ite (a2,b2,c2) ->
|
| Ite (a1,b1,c1), Ite (a2,b2,c2) ->
|
||||||
sub_eq a1 a2 && sub_eq b1 b2 && sub_eq c1 c2
|
sub_eq a1 a2 && sub_eq b1 b2 && sub_eq c1 c2
|
||||||
| (Bool _ | App_fun _ | Eq _ | Not _ | Ite _), _
|
| LRA l1, LRA l2 ->
|
||||||
|
begin match l1, l2 with
|
||||||
|
| LRA_pred (p1,a1,b1), LRA_pred (p2,a2,b2) ->
|
||||||
|
p1 = p2 && sub_eq a1 a2 && sub_eq b1 b2
|
||||||
|
| LRA_op(p1,a1,b1), LRA_op (p2,a2,b2) ->
|
||||||
|
p1 = p2 && sub_eq a1 a2 && sub_eq b1 b2
|
||||||
|
| LRA_const a1, LRA_const a2 -> Q.equal a1 a2
|
||||||
|
| LRA_other x1, LRA_other x2 -> sub_eq x1 x2
|
||||||
|
| (LRA_pred _ | LRA_op _ | LRA_const _ | LRA_other _), _ -> false
|
||||||
|
end
|
||||||
|
| (Bool _ | App_fun _ | Eq _ | Not _ | Ite _ | LRA _), _
|
||||||
-> false
|
-> false
|
||||||
|
|
||||||
let pp = pp_term_view_gen ~pp_id:ID.pp_name ~pp_t:A.pp
|
let pp = pp_term_view_gen ~pp_id:ID.pp_name ~pp_t:A.pp
|
||||||
|
|
@ -605,6 +660,7 @@ end = struct
|
||||||
| _ -> Not t
|
| _ -> Not t
|
||||||
|
|
||||||
let ite a b c = Ite (a,b,c)
|
let ite a b c = Ite (a,b,c)
|
||||||
|
let lra l : t = LRA l
|
||||||
|
|
||||||
let ty (t:t): Ty.t = match t with
|
let ty (t:t): Ty.t = match t with
|
||||||
| Bool _ | Eq _ | Not _ -> Ty.bool
|
| Bool _ | Eq _ | Not _ -> Ty.bool
|
||||||
|
|
@ -635,6 +691,12 @@ end = struct
|
||||||
| Fun_select s -> Lazy.force s.select_ty
|
| Fun_select s -> Lazy.force s.select_ty
|
||||||
| Fun_cstor c -> Lazy.force c.cstor_ty
|
| Fun_cstor c -> Lazy.force c.cstor_ty
|
||||||
end
|
end
|
||||||
|
| LRA l ->
|
||||||
|
begin match l with
|
||||||
|
| LRA_pred _ -> Ty.bool
|
||||||
|
| LRA_op _ | LRA_const _ -> Ty.real
|
||||||
|
| LRA_other x -> x.term_ty
|
||||||
|
end
|
||||||
|
|
||||||
let iter f view =
|
let iter f view =
|
||||||
match view with
|
match view with
|
||||||
|
|
@ -643,6 +705,12 @@ end = struct
|
||||||
| Not u -> f u
|
| Not u -> f u
|
||||||
| Eq (a,b) -> f a; f b
|
| Eq (a,b) -> f a; f b
|
||||||
| Ite (a,b,c) -> f a; f b; f c
|
| Ite (a,b,c) -> f a; f b; f c
|
||||||
|
| LRA l ->
|
||||||
|
begin match l with
|
||||||
|
| LRA_pred (_, a, b)|LRA_op (_, a, b) -> f a; f b
|
||||||
|
| LRA_const _ -> ()
|
||||||
|
| LRA_other x -> f x
|
||||||
|
end
|
||||||
|
|
||||||
let map f view =
|
let map f view =
|
||||||
match view with
|
match view with
|
||||||
|
|
@ -651,6 +719,7 @@ end = struct
|
||||||
| Not u -> Not (f u)
|
| Not u -> Not (f u)
|
||||||
| Eq (a,b) -> Eq (f a, f b)
|
| Eq (a,b) -> Eq (f a, f b)
|
||||||
| Ite (a,b,c) -> Ite (f a, f b, f c)
|
| Ite (a,b,c) -> Ite (f a, f b, f c)
|
||||||
|
| LRA l -> LRA (Sidekick_lra.map_view f l)
|
||||||
|
|
||||||
module Tbl = CCHashtbl.Make(struct
|
module Tbl = CCHashtbl.Make(struct
|
||||||
type t = term view
|
type t = term view
|
||||||
|
|
@ -672,6 +741,7 @@ module Term : sig
|
||||||
| Eq of 'a * 'a
|
| Eq of 'a * 'a
|
||||||
| Not of 'a
|
| Not of 'a
|
||||||
| Ite of 'a * 'a * 'a
|
| Ite of 'a * 'a * 'a
|
||||||
|
| LRA of 'a lra_view
|
||||||
|
|
||||||
val id : t -> int
|
val id : t -> int
|
||||||
val view : t -> term view
|
val view : t -> term view
|
||||||
|
|
@ -697,6 +767,7 @@ module Term : sig
|
||||||
val select : state -> select -> t -> t
|
val select : state -> select -> t -> t
|
||||||
val app_cstor : state -> cstor -> t IArray.t -> t
|
val app_cstor : state -> cstor -> t IArray.t -> t
|
||||||
val is_a : state -> cstor -> t -> t
|
val is_a : state -> cstor -> t -> t
|
||||||
|
val lra : state -> t lra_view -> t
|
||||||
|
|
||||||
(** Obtain unsigned version of [t], + the sign as a boolean *)
|
(** Obtain unsigned version of [t], + the sign as a boolean *)
|
||||||
val abs : state -> t -> t * bool
|
val abs : state -> t -> t * bool
|
||||||
|
|
@ -743,6 +814,7 @@ end = struct
|
||||||
| Eq of 'a * 'a
|
| Eq of 'a * 'a
|
||||||
| Not of 'a
|
| Not of 'a
|
||||||
| Ite of 'a * 'a * 'a
|
| Ite of 'a * 'a * 'a
|
||||||
|
| LRA of 'a lra_view
|
||||||
|
|
||||||
let[@inline] id t = t.term_id
|
let[@inline] id t = t.term_id
|
||||||
let[@inline] ty t = t.term_ty
|
let[@inline] ty t = t.term_ty
|
||||||
|
|
@ -804,6 +876,9 @@ end = struct
|
||||||
let is_a st c t : t = app_fun st (Fun.is_a c) (IArray.singleton t)
|
let is_a st c t : t = app_fun st (Fun.is_a c) (IArray.singleton t)
|
||||||
let app_cstor st c args : t = app_fun st (Fun.cstor c) args
|
let app_cstor st c args : t = app_fun st (Fun.cstor c) args
|
||||||
|
|
||||||
|
let[@inline] lra (st:state) (l:t lra_view) : t =
|
||||||
|
make st (Term_cell.lra l)
|
||||||
|
|
||||||
(* might need to tranfer the negation from [t] to [sign] *)
|
(* might need to tranfer the negation from [t] to [sign] *)
|
||||||
let abs tst t : t * bool = match view t with
|
let abs tst t : t * bool = match view t with
|
||||||
| Bool false -> true_ tst, false
|
| Bool false -> true_ tst, false
|
||||||
|
|
@ -828,6 +903,7 @@ end = struct
|
||||||
| Eq (a,b) -> C.Eq (a, b)
|
| Eq (a,b) -> C.Eq (a, b)
|
||||||
| Not u -> C.Not u
|
| Not u -> C.Not u
|
||||||
| Ite (a,b,c) -> C.If (a,b,c)
|
| Ite (a,b,c) -> C.If (a,b,c)
|
||||||
|
| LRA _ -> C.Opaque t (* no congruence here *)
|
||||||
|
|
||||||
module As_key = struct
|
module As_key = struct
|
||||||
type t = term
|
type t = term
|
||||||
|
|
@ -877,6 +953,7 @@ end = struct
|
||||||
| Not u -> not_ tst (f u)
|
| Not u -> not_ tst (f u)
|
||||||
| Eq (a,b) -> eq tst (f a) (f b)
|
| Eq (a,b) -> eq tst (f a) (f b)
|
||||||
| Ite (a,b,c) -> ite tst (f a) (f b) (f c)
|
| Ite (a,b,c) -> ite tst (f a) (f b) (f c)
|
||||||
|
| LRA l -> lra tst (Sidekick_lra.map_view f l)
|
||||||
end
|
end
|
||||||
|
|
||||||
module Value : sig
|
module Value : sig
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,14 @@ let eval (m:t) (t:Term.t) : Value.t option =
|
||||||
let a = aux a in
|
let a = aux a in
|
||||||
let b = aux b in
|
let b = aux b in
|
||||||
if Value.equal a b then Value.true_ else Value.false_
|
if Value.equal a b then Value.true_ else Value.false_
|
||||||
|
| LRA _l ->
|
||||||
|
assert false
|
||||||
|
(* TODO: evaluation
|
||||||
|
begin match l with
|
||||||
|
| LRA_pred (p, a, b) ->
|
||||||
|
| LRA_op (_, _, _)|LRA_const _|LRA_other _ -> assert false
|
||||||
|
end
|
||||||
|
*)
|
||||||
| App_fun (c, args) ->
|
| App_fun (c, args) ->
|
||||||
match Fun.view c, (args :_ IArray.t:> _ array) with
|
match Fun.view c, (args :_ IArray.t:> _ array) with
|
||||||
| Fun_def udef, _ ->
|
| Fun_def udef, _ ->
|
||||||
|
|
@ -180,7 +188,7 @@ let eval (m:t) (t:Term.t) : Value.t option =
|
||||||
| Fun_is_a _, _ ->
|
| Fun_is_a _, _ ->
|
||||||
Error.errorf "bad is-a term %a" Term.pp t
|
Error.errorf "bad is-a term %a" Term.pp t
|
||||||
| Fun_undef _, _ ->
|
| Fun_undef _, _ ->
|
||||||
try Term.Map.find t m.values
|
(try Term.Map.find t m.values
|
||||||
with Not_found ->
|
with Not_found ->
|
||||||
begin match Fun.Map.find c m.funs with
|
begin match Fun.Map.find c m.funs with
|
||||||
| fi ->
|
| fi ->
|
||||||
|
|
@ -191,7 +199,7 @@ let eval (m:t) (t:Term.t) : Value.t option =
|
||||||
end
|
end
|
||||||
| exception Not_found ->
|
| exception Not_found ->
|
||||||
raise No_value (* no particular interpretation *)
|
raise No_value (* no particular interpretation *)
|
||||||
end
|
end)
|
||||||
in
|
in
|
||||||
try Some (aux t)
|
try Some (aux t)
|
||||||
with No_value -> None
|
with No_value -> None
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
(name sidekick_base_term)
|
(name sidekick_base_term)
|
||||||
(public_name sidekick.base-term)
|
(public_name sidekick.base-term)
|
||||||
(synopsis "Basic term definitions for the standalone SMT solver")
|
(synopsis "Basic term definitions for the standalone SMT solver")
|
||||||
(libraries containers sidekick.core sidekick.util zarith)
|
(libraries containers sidekick.core sidekick.util sidekick.th-lra zarith)
|
||||||
(flags :standard -w -32 -open Sidekick_util))
|
(flags :standard -w -32 -open Sidekick_util))
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,6 @@ end)
|
||||||
|
|
||||||
module Th_lra = Sidekick_lra.Make(struct
|
module Th_lra = Sidekick_lra.Make(struct
|
||||||
module S = Solver
|
module S = Solver
|
||||||
module T = S.T.Term
|
|
||||||
type term = S.T.Term.t
|
type term = S.T.Term.t
|
||||||
|
|
||||||
include Lra
|
include Lra
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,14 @@ type 'a lra_view =
|
||||||
| LRA_const of Q.t
|
| LRA_const of Q.t
|
||||||
| LRA_other of 'a
|
| LRA_other of 'a
|
||||||
|
|
||||||
|
let map_view f (l:_ lra_view) : _ lra_view =
|
||||||
|
begin match l with
|
||||||
|
| LRA_pred (p, a, b) -> LRA_pred (p, f a, f b)
|
||||||
|
| LRA_op (p, a, b) -> LRA_op (p, f a, f b)
|
||||||
|
| LRA_const q -> LRA_const q
|
||||||
|
| LRA_other x -> LRA_other (f x)
|
||||||
|
end
|
||||||
|
|
||||||
module type ARG = sig
|
module type ARG = sig
|
||||||
module S : Sidekick_core.SOLVER
|
module S : Sidekick_core.SOLVER
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue