summaryrefslogtreecommitdiff
path: root/abstract/formula_printer.ml
diff options
context:
space:
mode:
Diffstat (limited to 'abstract/formula_printer.ml')
-rw-r--r--abstract/formula_printer.ml133
1 files changed, 108 insertions, 25 deletions
diff --git a/abstract/formula_printer.ml b/abstract/formula_printer.ml
index 7e626f0..994c82a 100644
--- a/abstract/formula_printer.ml
+++ b/abstract/formula_printer.ml
@@ -1,6 +1,15 @@
+open Ast
open Formula
open Ast_printer
+let string_of_binary_rel = function
+ | AST_EQ -> "="
+ | AST_NE -> "≠"
+ | AST_LT -> "<"
+ | AST_LE -> "≤"
+ | AST_GT -> ">"
+ | AST_GE -> "≥"
+
let ne_prec = function
| NUnary(op, _) -> unary_precedence
| NBinary(op, _, _) -> binary_op_precedence op
@@ -13,44 +22,118 @@ let be_prec = function
| BNot _ -> unary_precedence
| _ -> 100
+let is_or = function
+ | BOr _ -> true
+ | _ -> false
+let is_and = function
+ | BAnd _ -> true
+ | _ -> false
+
-let print_lh fmt pf fa a fe e =
+let print_ch fmt pf fa a fe e =
if fa a < fe e
- then Format.fprintf fmt "@[<2>(%a)@]" pf a
- else Format.fprintf fmt "%a" pf a
-let print_rh fmt pf fb b fe e =
- if fb b < fe e
- then Format.fprintf fmt "@[<2>(%a)@]" pf b
- else Format.fprintf fmt "%a" pf b
+ then Format.fprintf fmt "@[<hv 2>(%a)@]" pf a
+ else Format.fprintf fmt "@[<hv 2>%a@]" pf a
+let print_ah fmt pf fa a fe e =
+ if fa a <= fe e
+ then Format.fprintf fmt "@[<hv 2>(%a)@]" pf a
+ else Format.fprintf fmt "@[<hv 2>%a@]" pf a
let rec print_num_expr fmt e = match e with
| NIntConst i -> Format.fprintf fmt "%d" i
| NRealConst f -> Format.fprintf fmt "%f" f
- | NIdent id -> Format.fprintf fmt "%s" id
+ | NIdent id ->
+ let re = Str.regexp "/" in
+ Format.fprintf fmt "%s" (Str.global_replace re "·" id)
| NBinary(op, a, b) ->
- print_lh fmt print_num_expr ne_prec a ne_prec e;
- Format.fprintf fmt "@ %s@ " (string_of_binary_op op);
- print_rh fmt print_num_expr ne_prec b ne_prec e
+ print_ch fmt print_num_expr ne_prec a ne_prec e;
+ Format.fprintf fmt "@ %s " (string_of_binary_op op);
+ print_ah fmt print_num_expr ne_prec b ne_prec e
| NUnary(op, a) ->
- Format.pp_print_string fmt (string_of_unary_op op);
- print_rh fmt print_num_expr ne_prec a ne_prec e
+ Format.fprintf fmt "%s " (string_of_unary_op op);
+ print_ah fmt print_num_expr ne_prec a ne_prec e
+
+(* Print boolean form of formula *)
let rec print_bool_expr fmt e = match e with
| BConst b -> Format.fprintf fmt "%s" (if b then "true" else "false")
| BRel(op, a, b) ->
- print_lh fmt print_num_expr ne_prec a be_prec e;
- Format.fprintf fmt "@ %s@ " (string_of_binary_rel op);
- print_rh fmt print_num_expr ne_prec b be_prec e
+ print_ch fmt print_num_expr ne_prec a be_prec e;
+ Format.fprintf fmt "@ %s " (string_of_binary_rel op);
+ print_ch fmt print_num_expr ne_prec b be_prec e
| BAnd (a, b) ->
- print_lh fmt print_bool_expr be_prec a be_prec e;
- Format.fprintf fmt "@ /\\@ ";
- print_rh fmt print_bool_expr be_prec b be_prec e
+
+ if is_and a then
+ Format.fprintf fmt "%a" print_bool_expr a
+ else
+ if be_prec a < be_prec e || is_or a
+ then Format.fprintf fmt "@[<hv 2>(%a)@]" print_bool_expr a
+ else Format.fprintf fmt "@[<hv 2>%a@]" print_bool_expr a;
+ Format.fprintf fmt "@ ∧ ";
+ if is_and b then
+ Format.fprintf fmt "%a" print_bool_expr b
+ else
+ if be_prec b < be_prec e || is_or b
+ then Format.fprintf fmt "@[<hv 2>(%a)@]" print_bool_expr b
+ else Format.fprintf fmt "@[<hv 2>%a@]" print_bool_expr b
+
| BOr (a, b) ->
- print_lh fmt print_bool_expr be_prec a be_prec e;
- Format.fprintf fmt "@ \\/@ ";
- print_rh fmt print_bool_expr be_prec b be_prec e
+ print_ch fmt print_bool_expr be_prec a be_prec e;
+ Format.fprintf fmt "@ ∨ ";
+ print_ch fmt print_bool_expr be_prec b be_prec e
| BNot (a) ->
- Format.pp_print_string fmt "!";
- print_rh fmt print_bool_expr be_prec a be_prec e
+ Format.pp_print_string fmt "¬";
+ print_ch fmt print_bool_expr be_prec a be_prec e
+
+let print_expr fmt e =
+ Format.fprintf fmt "@[<hv 2>%a@]" print_bool_expr e
+
+
+(* Print constraint list form of formula *)
+
+let print_cons fmt (eq, sg) =
+ let sg_str = match sg with
+ | CONS_EQ -> "="
+ | CONS_NE -> "≠"
+ | CONS_GT -> ">"
+ | CONS_GE -> "≥"
+ in
+ Format.fprintf fmt "@[<hv 2>%a %s 0@]"
+ print_num_expr eq sg_str
+
+let rec print_conslist fmt (cons, e) =
+ let rec aux = function
+ | [] -> false
+ | [a] ->
+ Format.fprintf fmt "@[<hv 2>%a@]" print_cons a; true
+ | p::q ->
+ Format.fprintf fmt "@[<hv 2>%a@]" print_cons p;
+ Format.fprintf fmt "@ ∧ ";
+ aux q
+ in
+ match e with
+ | CLTrue ->
+ Format.fprintf fmt "@[<hv 2>(";
+ ignore (aux cons);
+ Format.fprintf fmt ")@]"
+ | CLFalse ->
+ Format.fprintf fmt "false"
+ | _ ->
+ Format.fprintf fmt "@[<hv 2>(";
+ if aux cons then Format.fprintf fmt "@ ∧ ";
+ print_conslist_expr fmt e;
+ Format.fprintf fmt ")@]"
+
+and print_conslist_expr fmt = function
+ | CLTrue -> Format.fprintf fmt "true"
+ | CLFalse -> Format.fprintf fmt "false"
+ | CLOr(a, b) ->
+ Format.fprintf fmt "@[<hv 2>(%a@ ∨ %a)@]"
+ print_conslist a
+ print_conslist b
+ | CLAnd(a, b) ->
+ Format.fprintf fmt "%a@ ∧ %a"
+ print_conslist_expr a
+ print_conslist_expr b
+
-let print_expr = print_bool_expr