Skip to content

Commit 7d7b66b

Browse files
committed
Adds Model.to_json (Closes #168)
1 parent ee5ff1f commit 7d7b66b

File tree

14 files changed

+145
-78
lines changed

14 files changed

+145
-78
lines changed

dune-project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
(and
5555
:build
5656
(>= "20220210")))
57+
yojson
5758
(odoc
5859
:with-doc)
5960
(bisect_ppx

lib/dune

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
(libraries
4646
hc
4747
ocaml_intrinsics
48+
yojson
4849
(select
4950
colibri2_mappings.ml
5051
from

lib/model.ml

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,46 @@
1818

1919
type t = (Symbol.t, Value.t) Hashtbl.t
2020

21+
22+
let iter f model = Hashtbl.iter (fun a b -> f (a, b)) model
23+
2124
let get_symbols (model : t) : Symbol.t List.t =
2225
Hashtbl.to_seq_keys model |> List.of_seq |> List.sort Symbol.compare
2326

2427
let compare_bindings (s1, v1) (s2, v2) =
2528
let compare_symbol = Symbol.compare s1 s2 in
2629
if compare_symbol = 0 then Value.compare v1 v2 else compare_symbol
2730

28-
let get_bindings (model : t) : (Symbol.t * Value.t) List.t =
31+
let get_bindings (model : t) : (Symbol.t * Value.t) list =
2932
Hashtbl.to_seq model |> List.of_seq |> List.sort compare_bindings
3033

31-
let evaluate (model : t) (symb : Symbol.t) : Value.t Option.t =
34+
let evaluate (model : t) (symb : Symbol.t) : Value.t option =
3235
Hashtbl.find_opt model symb
3336

34-
let pp_print_hashtbl ~pp_sep pp_v fmt v =
35-
let l = Hashtbl.to_seq v |> List.of_seq |> List.sort compare_bindings in
36-
Format.pp_print_list ~pp_sep pp_v fmt l
37-
3837
let pp_bindings fmt ?(no_values = false) model =
39-
pp_print_hashtbl
38+
Format.pp_print_list
4039
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
4140
(fun fmt (key, data) ->
4241
if not no_values then
4342
Format.fprintf fmt "(%a %a)" Symbol.pp key Value.pp data
4443
else
4544
let t = Symbol.type_of key in
4645
Format.fprintf fmt "(%a %a)" Symbol.pp key Ty.pp t )
47-
fmt model
46+
fmt (get_bindings model)
4847

4948
let pp fmt ?(no_values = false) model =
5049
Format.fprintf fmt "(model@\n @[<v>%a@])" (pp_bindings ~no_values) model
5150

52-
let to_string (model : t) : String.t =
51+
let to_string (model : t) : string =
5352
Format.asprintf "%a" (pp ~no_values:false) model
53+
54+
let to_json (model : t) : Yojson.t =
55+
let model :> Yojson.t list =
56+
Hashtbl.fold
57+
(fun s v acc ->
58+
let s = Symbol.to_json s in
59+
let v = `Assoc [ ("value", Value.to_json v) ] in
60+
Yojson.Basic.Util.combine s v :: acc )
61+
model []
62+
in
63+
`Assoc [ ("model", `List model) ]

lib/model.mli

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@
1818

1919
type t = (Symbol.t, Value.t) Hashtbl.t
2020

21-
val get_symbols : t -> Symbol.t List.t
21+
val iter : (Symbol.t * Value.t -> unit) -> t -> unit
2222

23-
val get_bindings : t -> (Symbol.t * Value.t) List.t
23+
val get_symbols : t -> Symbol.t list
2424

25-
val evaluate : t -> Symbol.t -> Value.t Option.t
25+
(** bindings are sorted by symbol *)
26+
val get_bindings : t -> (Symbol.t * Value.t) list
2627

27-
val pp : Format.formatter -> ?no_values:bool -> t -> Unit.t
28+
val evaluate : t -> Symbol.t -> Value.t option
2829

29-
val to_string : t -> String.t
30+
val pp : Format.formatter -> ?no_values:bool -> t -> unit
31+
32+
val to_string : t -> string
33+
34+
val to_json : t -> Yojson.t

lib/num.ml

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,6 @@ type t =
2323
| F32 of int32
2424
| F64 of int64
2525

26-
let equal (n1 : t) (n2 : t) : bool =
27-
match (n1, n2) with
28-
| I8 i1, I8 i2 -> i1 = i2
29-
| I32 i1, I32 i2 -> i1 = i2
30-
| I64 i1, I64 i2 -> i1 = i2
31-
| F32 i1, F32 i2 -> Int32.float_of_bits i1 = Int32.float_of_bits i2
32-
| F64 i1, F64 i2 -> Int64.float_of_bits i1 = Int64.float_of_bits i2
33-
| I8 _, _ | I32 _, _ | I64 _, _ | F32 _, _ | F64 _, _ -> false
34-
3526
let compare n1 n2 =
3627
match (n1, n2) with
3728
| I8 i1, I8 i2 -> compare i1 i2
@@ -45,13 +36,16 @@ let compare n1 n2 =
4536
*)
4637
| I8 _, _ | I32 _, _ | I64 _, _ | F32 _, _ | F64 _, _ -> compare n1 n2
4738

48-
let type_of (n : t) =
49-
match n with
50-
| I8 _ -> Ty.(Ty_bitv 8)
51-
| I32 _ -> Ty.(Ty_bitv 32)
52-
| I64 _ -> Ty.(Ty_bitv 64)
53-
| F32 _ -> Ty.(Ty_fp 32)
54-
| F64 _ -> Ty.(Ty_fp 64)
39+
let equal (n1 : t) (n2 : t) : bool =
40+
match (n1, n2) with
41+
| I8 i1, I8 i2 -> i1 = i2
42+
| I32 i1, I32 i2 -> i1 = i2
43+
| I64 i1, I64 i2 -> i1 = i2
44+
| F32 i1, F32 i2 -> Int32.float_of_bits i1 = Int32.float_of_bits i2
45+
| F64 i1, F64 i2 -> Int64.float_of_bits i1 = Int64.float_of_bits i2
46+
| I8 _, _ | I32 _, _ | I64 _, _ | F32 _, _ | F64 _, _ -> false
47+
48+
let num_of_bool (b : bool) : t = I32 (if b then 1l else 0l)
5549

5650
let pp fmt (n : t) =
5751
match n with
@@ -63,4 +57,12 @@ let pp fmt (n : t) =
6357

6458
let to_string (n : t) : string = Format.asprintf "%a" pp n
6559

66-
let num_of_bool (b : bool) : t = I32 (if b then 1l else 0l)
60+
let to_json (n : t) : Yojson.Basic.t = `String (to_string n)
61+
62+
let type_of (n : t) =
63+
match n with
64+
| I8 _ -> Ty.(Ty_bitv 8)
65+
| I32 _ -> Ty.(Ty_bitv 32)
66+
| I64 _ -> Ty.(Ty_bitv 64)
67+
| F32 _ -> Ty.(Ty_fp 32)
68+
| F64 _ -> Ty.(Ty_fp 64)

lib/num.mli

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ type t =
2323
| F32 of int32
2424
| F64 of int64
2525

26-
val equal : t -> t -> bool
27-
2826
val compare : t -> t -> int
2927

30-
val type_of : t -> Ty.t
28+
val equal : t -> t -> bool
29+
30+
val num_of_bool : bool -> t
3131

3232
val pp : Format.formatter -> t -> unit
3333

3434
val to_string : t -> string
3535

36-
val num_of_bool : bool -> t
36+
val to_json : t -> Yojson.Basic.t
37+
38+
val type_of : t -> Ty.t

lib/symbol.ml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,26 @@ type t =
2323

2424
let ( @: ) (name : string) (ty : Ty.t) : t = { name; ty }
2525

26-
let make (ty : Ty.t) (name : string) : t = name @: ty
27-
28-
let mk_symbol (ty : Ty.t) (name : string) : t = name @: ty
29-
30-
let equal (s1 : t) (s2 : t) : bool =
31-
Ty.equal s1.ty s2.ty && String.equal s1.name s2.name
32-
3326
let compare (t1 : t) (t2 : t) : int =
3427
let compare_name = compare t1.name t2.name in
3528
if compare_name = 0 then compare t1.ty t2.ty else compare_name
3629

37-
let rename (symbol : t) (name : string) : t = { symbol with name }
30+
let equal (s1 : t) (s2 : t) : bool =
31+
Ty.equal s1.ty s2.ty && String.equal s1.name s2.name
3832

39-
let type_of ({ ty; _ } : t) : Ty.t = ty
33+
let make (ty : Ty.t) (name : string) : t = name @: ty
34+
35+
let mk_symbol (ty : Ty.t) (name : string) : t = name @: ty
4036

4137
let pp (fmt : Format.formatter) ({ name; _ } : t) : unit =
4238
Format.pp_print_string fmt name
4339

40+
let rename (symbol : t) (name : string) : t = { symbol with name }
41+
4442
let to_string ({ name; _ } : t) : string = name
43+
44+
let to_json ({ name; ty } : t) : Yojson.Basic.t =
45+
`Assoc
46+
[ ("name", `String name); ("ty", `String (Format.asprintf "%a" Ty.pp ty)) ]
47+
48+
let type_of ({ ty; _ } : t) : Ty.t = ty

lib/symbol.mli

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,20 @@ type t =
2323

2424
val ( @: ) : string -> Ty.t -> t
2525

26+
val compare : t -> t -> int
27+
28+
val equal : t -> t -> Bool.t
29+
2630
val make : Ty.t -> string -> t
2731

2832
val mk_symbol : Ty.t -> string -> t [@@deprecated "Please use 'make' instead"]
2933

30-
val equal : t -> t -> Bool.t
34+
val pp : Format.formatter -> t -> unit
3135

3236
val rename : t -> string -> t
3337

34-
val type_of : t -> Ty.t
35-
3638
val to_string : t -> string
3739

38-
val compare : t -> t -> int
40+
val to_json : t -> Yojson.Basic.t
3941

40-
val pp : Format.formatter -> t -> unit
42+
val type_of : t -> Ty.t

lib/value.ml

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,7 @@ type t =
2828
| List of t list
2929
| App : [> `Op of string ] * t list -> t
3030

31-
let rec equal (v1 : t) (v2 : t) : Bool.t =
32-
match (v1, v2) with
33-
| True, True | False, False -> true
34-
| Int x1, Int x2 -> Int.equal x1 x2
35-
| Real x1, Real x2 -> x1 = x2
36-
| Str x1, Str x2 -> String.equal x1 x2
37-
| Num x1, Num x2 -> Num.equal x1 x2
38-
| List l1, List l2 -> List.equal equal l1 l2
39-
| App (`Op op1, vs1), App (`Op op2, vs2) ->
40-
String.equal op1 op2 && List.equal equal vs1 vs2
41-
| _ -> false
42-
43-
let rec compare v1 v2 =
31+
let rec compare (v1 : t) (v2 : t) : int =
4432
match (v1, v2) with
4533
| True, True | False, False -> 0
4634
| False, True -> -1
@@ -55,17 +43,19 @@ let rec compare v1 v2 =
5543
if c = 0 then List.compare compare vs1 vs2 else c
5644
| _ -> compare v1 v2
5745

58-
let type_of (v : t) : Ty.t =
59-
match v with
60-
| True | False -> Ty_bool
61-
| Int _ -> Ty_int
62-
| Real _ -> Ty_real
63-
| Str _ -> Ty_str
64-
| Num n -> Num.type_of n
65-
| List _ -> Ty_list
66-
| App _ -> Ty_app
46+
let rec equal (v1 : t) (v2 : t) : bool =
47+
match (v1, v2) with
48+
| True, True | False, False -> true
49+
| Int x1, Int x2 -> Int.equal x1 x2
50+
| Real x1, Real x2 -> x1 = x2
51+
| Str x1, Str x2 -> String.equal x1 x2
52+
| Num x1, Num x2 -> Num.equal x1 x2
53+
| List l1, List l2 -> List.equal equal l1 l2
54+
| App (`Op op1, vs1), App (`Op op2, vs2) ->
55+
String.equal op1 op2 && List.equal equal vs1 vs2
56+
| _ -> false
6757

68-
let rec pp fmt (v : t) =
58+
let rec pp (fmt : Format.formatter) (v : t) : unit =
6959
let open Format in
7060
match v with
7161
| True -> pp_print_string fmt "true"
@@ -84,4 +74,25 @@ let rec pp fmt (v : t) =
8474
vs
8575
| _ -> assert false
8676

87-
let to_string v = Format.asprintf "%a" pp v
77+
let to_string (v : t) : string = Format.asprintf "%a" pp v
78+
79+
let rec to_json (v : t) : Yojson.Basic.t =
80+
match v with
81+
| True -> `Bool true
82+
| False -> `Bool false
83+
| Int int -> `Int int
84+
| Real real -> `Float real
85+
| Str str -> `String str
86+
| Num n -> Num.to_json n
87+
| List l -> `List (List.map to_json l)
88+
| App _ -> assert false
89+
90+
let type_of (v : t) : Ty.t =
91+
match v with
92+
| True | False -> Ty_bool
93+
| Int _ -> Ty_int
94+
| Real _ -> Ty_real
95+
| Str _ -> Ty_str
96+
| Num n -> Num.type_of n
97+
| List _ -> Ty_list
98+
| App _ -> Ty_app

lib/value.mli

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ type t =
2626
| List of t list
2727
| App : [> `Op of string ] * t list -> t
2828

29-
val equal : t -> t -> bool
30-
3129
val compare : t -> t -> int
3230

33-
val type_of : t -> Ty.t
31+
val equal : t -> t -> bool
3432

3533
val pp : Format.formatter -> t -> unit
3634

3735
val to_string : t -> string
36+
37+
val to_json : t -> Yojson.Basic.t
38+
39+
val type_of : t -> Ty.t

0 commit comments

Comments
 (0)