Skip to content

Commit

Permalink
CN: Add implies logical binary operator for specs
Browse files Browse the repository at this point in the history
This commit adds `implies` as a new, infix logical binary operator for
the spec language.  It does not implement it for the runtime testing.
The reason we use a new keyword "implies" instead of a more natural
`==>` is that currently the lexer is shared between C and CN, and and so
we cannot add `==>` to CN without adding it to C, which is incorrect
because C does not support that token.

Fixes rems-project#329
  • Loading branch information
elaustell committed Jul 3, 2024
1 parent a1fa10d commit 28f159f
Show file tree
Hide file tree
Showing 22 changed files with 1,586 additions and 1,443 deletions.
4 changes: 2 additions & 2 deletions backend/cn/cn_internal_to_ail.ml
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ let cn_to_ail_binop_internal bt1 bt2 =
| SetDifference -> failwith "TODO cn_to_ail_binop: SetDifference"
| SetMember -> failwith "TODO cn_to_ail_binop: SetMember"
| Subset -> failwith "TODO cn_to_ail_binop: Subset"
| Impl -> failwith "TODO cn_to_ail_binop: Impl"
| Implies -> failwith "TODO cn_to_ail_binop: Impl"

(* Assume a specific shape, where sym appears on the RHS (i.e. in e2) *)

Expand Down Expand Up @@ -1449,7 +1449,7 @@ let cn_to_ail_logical_constraint_internal : type a. (_ Cn.cn_datatype) list -> (
cn_to_ail_expr_internal dts globals it d
| LogicalConstraints.Forall ((sym, bt), it) ->
let (cond_it, t) = match IT.term it with
| Binop (Impl, it, it') -> (it, it')
| Binop (Implies, it, it') -> (it, it')
| _ -> failwith "Incorrect form of forall logical constraint term"
in

Expand Down
2 changes: 2 additions & 0 deletions backend/cn/compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ module EffectfulTranslation = struct
return (IT (Binop (Or, e1, e2), SBT.Bool, loc))
| CN_and, SBT.Bool ->
return (IT (Binop (And, e1, e2), SBT.Bool, loc))
| CN_implies, SBT.Bool ->
return (IT (Binop (Implies, e1, e2), SBT.Bool, loc))
| CN_map_get, _ ->
let@ rbt = match IT.bt e1 with
| Map (_, rbt) -> return rbt
Expand Down
2 changes: 1 addition & 1 deletion backend/cn/diagnostics.ml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ let term_with_model_name nm cfg x =
let bool_subterms1 t = match IT.term t with
| IT.Binop (And, it,it') -> [it;it']
| IT.Binop (Or, it,it') -> [it;it']
| IT.Binop (Impl, x, y) -> [x; y]
| IT.Binop (Implies, x, y) -> [x; y]
| IT.Unop (Not, x) -> [x]
| IT.Binop (EQ, x, y) -> if BT.equal (IT.bt x) BT.Bool
then [x; y] else []
Expand Down
2 changes: 1 addition & 1 deletion backend/cn/eqTable.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ let add_eq_sym (guard, lhs, rhs) tab =

let add_one_eq (tab : table) (it : IT.t) = match IT.term it with
| IT.Binop (IT.EQ, x, y) -> add_eq_sym (None, x, y) tab
| IT.Binop (Impl, guard, x) -> begin match IT.is_eq x with
| IT.Binop (Implies, guard, x) -> begin match IT.is_eq x with
| Some (y, z) -> add_eq_sym (Some guard, y, z) tab
| _ -> tab
end
Expand Down
8 changes: 6 additions & 2 deletions backend/cn/indexTerms.ml
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,10 @@ let is_or = function
| IT (Binop (Or, it, it'), _, _) -> Some (it, it')
| _ -> None

let is_implies = function
| IT (Binop (Implies, it, it'), _, _) -> Some (it, it')
| _ -> None

let is_not = function
| IT (Unop (Not, it), _, _) -> Some it
| _ -> None
Expand Down Expand Up @@ -533,7 +537,7 @@ let and2_ (it, it') loc = IT (Binop (And, it, it'), BT.Bool, loc)
let or2_ (it, it') loc = IT (Binop (Or, it, it'), BT.Bool, loc)
let and_ its loc = vargs_binop (bool_ true loc) (Tools.curry (fun p -> and2_ p loc)) its
let or_ its loc = vargs_binop (bool_ false loc) (Tools.curry (fun p -> or2_ p loc)) its
let impl_ (it, it') loc = IT (Binop (Impl, it, it'), BT.Bool, loc)
let impl_ (it, it') loc = IT (Binop (Implies, it, it'), BT.Bool, loc)
let not_ it loc = IT (Unop (Not, it), bt it, loc)
let ite_ (it, it', it'') loc = IT (ITE (it, it', it''), bt it', loc)
let eq_ (it, it') loc =
Expand All @@ -558,7 +562,7 @@ let let_ ((nm, x), y) loc = IT (Let ((nm, x), y), basetype y, loc)
(* match term it with *)
(* | And xs -> or_ (List.map not_ xs) *)
(* | Or xs -> and_ (List.map not_ xs) *)
(* | Impl (x, y) -> and_ [x; not_ y] *)
(* | Implies (x, y) -> and_ [x; not_ y] *)
(* | _ -> not_ it *)


Expand Down
4 changes: 2 additions & 2 deletions backend/cn/lemmata.ml
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ let it_adjust (global : Global.t) it =
let x = f x in
let y = f y in
if IT.equal x y then IT.bool_ true loc else IT.eq__ x y loc
| IT.Binop (Impl, x, y) ->
| IT.Binop (Implies, x, y) ->
let x = f x in
let y = f y in
if IT.is_false x || IT.is_true y then IT.bool_ true loc else IT.impl_ (x, y) loc
Expand Down Expand Up @@ -788,7 +788,7 @@ let it_to_coq loc global list_mono it =
| LTPointer -> abinop (if enc_prop then "<" else "<?") x y
| And -> abinop (if enc_prop then "/\\" else "&&") x y
| Or -> abinop (if enc_prop then "\\/" else "||") x y
| Impl -> abinop (if enc_prop then "->" else "implb") x y
| Implies -> abinop (if enc_prop then "->" else "implb") x y
| _ -> do_fail "arith op"
end
| IT.Match (x, cases) ->
Expand Down
4 changes: 2 additions & 2 deletions backend/cn/simplify.ml
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ module IndexTerms = struct
| _ when IT.equal it1 it2 -> it1
| _ -> IT (Binop (Or, it1, it2), the_bt, the_loc)
end
| Binop (Impl, a, b) ->
| Binop (Implies, a, b) ->
let a = aux a in
let b = aux b in
if IT.equal a b then IT (Const (Bool true), the_bt, the_loc)
Expand All @@ -393,7 +393,7 @@ module IndexTerms = struct
| _, IT (Const (Bool false), _, _) ->
not_ a the_loc
| _ ->
IT (Binop (Impl, a, b), the_bt, the_loc)
IT (Binop (Implies, a, b), the_bt, the_loc)
end
| Unop (op, a) ->
let a = aux a in
Expand Down
2 changes: 1 addition & 1 deletion backend/cn/solver.ml
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ module Translate = struct
| LEPointer -> adj ()
| And -> Z3.Boolean.mk_and context (map term [t1;t2])
| Or -> Z3.Boolean.mk_or context (map term [t1;t2])
| Impl -> Z3.Boolean.mk_implies context (term t1) (term t2)
| Implies -> Z3.Boolean.mk_implies context (term t1) (term t2)
end
| ITE (t1, t2, t3) -> Z3.Boolean.mk_ite context (term t1) (term t2) (term t3)
| EachI _ -> adj ()
Expand Down
8 changes: 4 additions & 4 deletions backend/cn/terms.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type unop =
type binop =
| And
| Or
| Impl
| Implies
| Add
| Sub
| Mul
Expand Down Expand Up @@ -189,8 +189,8 @@ let pp : 'bt 'a. ?atomic:bool -> ?f:('bt term -> Pp.document -> Pp.document) ->
mparens (flow (break_op (ampersand ^^ ampersand)) [aux true it1; aux true it2])
| Or ->
mparens (flow (break_op (bar ^^ bar)) [aux true it1; aux true it2])
| Impl ->
mparens (flow (break_op (minus ^^ rangle ())) [aux true it1; aux true it2])
| Implies ->
c_app !^"implies" [aux true it1; aux true it2]
| Add ->
mparens (flow (break_op plus) [aux true it1; aux true it2])
| Sub ->
Expand Down Expand Up @@ -393,7 +393,7 @@ let rec dtree (IT (it_, bt, loc)) =
| Binop (op, t1, t2) ->
Dnode (pp_ctor (show_binop op), [dtree t1; dtree t2])
| ITE (t1, t2, t3) ->
Dnode (pp_ctor "Impl", [dtree t1; dtree t2; dtree t3])
Dnode (pp_ctor "Implies", [dtree t1; dtree t2; dtree t3])
| EachI ((starti,(i,_),endi), body) ->
Dnode (pp_ctor "EachI", [
Dleaf !^(string_of_int starti);
Expand Down
4 changes: 2 additions & 2 deletions backend/cn/wellTyped.ml
Original file line number Diff line number Diff line change
Expand Up @@ -551,10 +551,10 @@ module WIT = struct
let@ t = check loc Bool t in
let@ t' = check loc Bool t' in
return (IT (Binop (Or, t, t'), Bool, loc))
| Impl ->
| Implies ->
let@ t = check loc Bool t in
let@ t' = check loc Bool t' in
return (IT (Binop (Impl, t, t'), Bool, loc))
return (IT (Binop (Implies, t, t'), Bool, loc))
end
| ITE (t,t',t'') ->
let@ t = check loc Bool t in
Expand Down
1 change: 1 addition & 0 deletions frontend/model/cn.lem
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type cn_binop =
| CN_ge
| CN_or
| CN_and
| CN_implies
| CN_map_get


Expand Down
1 change: 1 addition & 0 deletions ocaml_frontend/cn_ocaml.ml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ module MakePp (Conf: PP_CN) = struct
| CN_ge -> P.rangle ^^ P.equals
| CN_or -> P.bar ^^ P.bar
| CN_and -> P.ampersand ^^ P.ampersand
| CN_implies -> P.equals ^^ P.equals ^^ P.rangle
| CN_map_get -> P.string "CN_map_get"

let pp_cn_c_kind = function
Expand Down
1 change: 0 additions & 1 deletion ocaml_frontend/pprinters/pp_ail.ml
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,6 @@ let pp_binaryOperator = function
| Eq -> P.equals ^^ P.equals
| Ne -> P.bang ^^ P.equals


let pp_unaryOperator = function
| Plus -> P.plus
| Minus -> P.minus
Expand Down
2 changes: 1 addition & 1 deletion parsers/c/c_lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ let keywords: (string * Tokens.token) list = [
"__volatile__", ASM_VOLATILE;
"__builtin_types_compatible_p", BUILTIN_TYPES_COMPATIBLE_P;
"__builtin_choose_expr", BUILTIN_CHOOSE_EXPR;

]

let lexicon: (string, token) Hashtbl.t =
Expand Down Expand Up @@ -150,6 +149,7 @@ let cn_keywords: (string * Tokens.token) list = [
"datatype" , CN_DATATYPE;
"type_synonym" , CN_TYPE_SYNONYM;
"_" , CN_WILD;
"implies" , CN_IMPLIES;
]

let cn_lexicon: (string, token) Hashtbl.t =
Expand Down
16 changes: 12 additions & 4 deletions parsers/c/c_parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ type asm_qualifier =
%token CN_LET CN_TAKE CN_OWNED CN_BLOCK CN_EACH CN_FUNCTION CN_LEMMA CN_PREDICATE
%token CN_DATATYPE CN_TYPE_SYNONYM CN_SPEC CN_ARRAY_SHIFT CN_MEMBER_SHIFT
%token CN_UNCHANGED CN_WILD CN_MATCH
%token CN_GOOD CN_NULL CN_TRUE CN_FALSE
%token CN_GOOD CN_NULL CN_TRUE CN_FALSE CN_IMPLIES
%token <string * [`U|`I] * int> CN_CONSTANT

%token EOF
Expand Down Expand Up @@ -1978,10 +1978,18 @@ bool_and_expr:
| e1= bool_and_expr AMPERSAND_AMPERSAND e2= rel_expr
{ Cerb_frontend.Cn.(CNExpr ( Cerb_location.(region ($startpos, $endpos) (PointCursor $startpos($2)))
, CNExpr_binop (CN_and, e1, e2))) }
bool_or_expr:

bool_implies_expr:
| e = bool_and_expr
{ e }
| e1= bool_or_expr PIPE_PIPE e2= bool_and_expr
| e1= bool_and_expr CN_IMPLIES e2= bool_implies_expr (* implication arrow ==> *)
{ Cerb_frontend.Cn.(CNExpr ( Cerb_location.(region ($startpos, $endpos) (PointCursor $startpos($2)))
, CNExpr_binop (CN_implies, e1, e2))) }

bool_or_expr:
| e = bool_implies_expr
{ e }
| e1= bool_or_expr PIPE_PIPE e2= bool_implies_expr
{ Cerb_frontend.Cn.(CNExpr ( Cerb_location.(region ($startpos, $endpos) (PointCursor $startpos($2)))
, CNExpr_binop (CN_or, e1, e2))) }

Expand Down Expand Up @@ -2497,4 +2505,4 @@ cn_toplevel:
{ elems }


(* END CN *)
(* END CN *)
Loading

0 comments on commit 28f159f

Please sign in to comment.