Skip to content

Commit

Permalink
New equality metric that compares numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
Leonidas-from-XIV committed Jun 28, 2024
1 parent ce6e250 commit b19fe7a
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 41 deletions.
4 changes: 4 additions & 0 deletions lib/dune
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
(:out t.cppo.ml)
type.ml
monomorphic.ml
equal.cppo.ml
prettyprint.ml
write.ml
write2.ml)
Expand All @@ -33,6 +34,7 @@
write.ml
prettyprint.ml
monomorphic.ml
equal.cppo.ml
write2.ml
read.ml
util.ml)
Expand Down Expand Up @@ -62,6 +64,7 @@
write.ml
prettyprint.ml
monomorphic.ml
equal.cppo.ml
write2.ml
read.ml
util.ml)
Expand Down Expand Up @@ -91,6 +94,7 @@
write.ml
prettyprint.ml
monomorphic.ml
equal.cppo.ml
write2.ml
read.ml
util.ml)
Expand Down
60 changes: 60 additions & 0 deletions lib/equal.cppo.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
let rec equal a b =
let [@warning "-26"] float_int_equal f i = (float_of_int i) = f in
match a, b with
| `Null, `Null -> true
| `Bool a, `Bool b -> a = b
#ifdef INT
| `Int a, `Int b -> a = b
#endif
#ifdef INTLIT
| `Intlit a, `Intlit b -> a = b
#ifdef NUMERIC_EQUAL
#ifdef INT
| `Intlit s, `Int i
| `Int i, `Intlit s -> (string_of_int i) = s
#endif
#endif
#endif
#ifdef FLOAT
| `Float a, `Float b -> a = b
#ifdef NUMERIC_EQUAL
#ifdef INT
| `Float f, `Int i
| `Int i, `Float f -> float_int_equal f i
#endif
#endif
#endif
#ifdef FLOATLIT
| `Floatlit a, `Floatlit b -> a = b
#ifdef NUMERIC_EQUAL
#ifdef FLOAT
| `Floatlit l, `Float f
| `Float f, `Floatlit l -> (string_of_float f) = l
#endif
#endif
#endif
#ifdef STRING
| `String a, `String b -> a = b
#endif
#ifdef STRINGLIT
| `Stringlit a, `Stringlit b -> a = b
#endif
| `Assoc xs, `Assoc ys ->
let compare_keys = fun (key, _) (key', _) -> String.compare key key' in
let xs = List.stable_sort compare_keys xs in
let ys = List.stable_sort compare_keys ys in
(match List.for_all2 (fun (key, value) (key', value') ->
match key = key' with
| false -> false
| true -> equal value value') xs ys with
| result -> result
| exception Invalid_argument _ ->
(* the lists were of different lengths, thus unequal *)
false)
| `List xs, `List ys ->
(match List.for_all2 equal xs ys with
| result -> result
| exception Invalid_argument _ ->
(* the lists were of different lengths, thus unequal *)
false)
| _ -> false
52 changes: 11 additions & 41 deletions lib/monomorphic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,44 +71,14 @@ let rec pp fmt =
let show x =
Format.asprintf "%a" pp x

let rec equal a b =
match a, b with
| `Null, `Null -> true
| `Bool a, `Bool b -> a = b
#ifdef INT
| `Int a, `Int b -> a = b
#endif
#ifdef INTLIT
| `Intlit a, `Intlit b -> a = b
#endif
#ifdef FLOAT
| `Float a, `Float b -> a = b
#endif
#ifdef FLOATLIT
| `Floatlit a, `Floatlit b -> a = b
#endif
#ifdef STRING
| `String a, `String b -> a = b
#endif
#ifdef STRINGLIT
| `Stringlit a, `Stringlit b -> a = b
#endif
| `Assoc xs, `Assoc ys ->
let compare_keys = fun (key, _) (key', _) -> String.compare key key' in
let xs = List.stable_sort compare_keys xs in
let ys = List.stable_sort compare_keys ys in
(match List.for_all2 (fun (key, value) (key', value') ->
match key = key' with
| false -> false
| true -> equal value value') xs ys with
| result -> result
| exception Invalid_argument _ ->
(* the lists were of different lengths, thus unequal *)
false)
| `List xs, `List ys ->
(match List.for_all2 equal xs ys with
| result -> result
| exception Invalid_argument _ ->
(* the lists were of different lengths, thus unequal *)
false)
| _ -> false
let equal a b =
#include "equal.cppo.ml"
in
equal a b

let numeric_equal a b =
#define NUMERIC_EQUAL
#include "equal.cppo.ml"
#undef NUMERIC_EQUAL
in
equal a b
8 changes: 8 additions & 0 deletions lib/monomorphic.mli
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,11 @@ val equal : t -> t -> bool
duplicate keys which will be considered equal as long as they are in the
same input order.
*)

val numeric_equal : t -> t -> bool
(** [numeric_equal a b] determines whether [a] and [b] are equal, while
attempting to preserve equality according to JSON rules which do not
distinguish between float and integers.
The remaining semantics are identical to [equal].
*)

0 comments on commit b19fe7a

Please sign in to comment.