-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lean: add support for vectors and register vectors #911
Conversation
@@ -377,7 +380,9 @@ let rec doc_exp (as_monadic : bool) ctx (E_aux (e, (l, annot)) as full_exp) = | |||
let d_args = List.map d_of_arg args in | |||
let fn_monadic = not (Effects.function_is_pure f ctx.global.effect_info) in | |||
nest 2 (wrap_with_pure (as_monadic && fn_monadic) (parens (flow (break 1) (d_id :: d_args)))) | |||
| E_vector vals -> failwith "vector found" | |||
| E_vector vals -> | |||
let vals = List.map (doc_exp false ctx) vals in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work for effectful subexpressions? Tuples use d_of_arg
, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not tested that, but using the same method as tuples is probably correct, I'll change it accordingly
lib/flow.sail
Outdated
@@ -75,7 +75,7 @@ val eq_int = pure {ocaml: "eq_int", interpreter: "eq_int", lem: "eq", coq: "Z.eq | |||
|
|||
val eq_bool = pure {ocaml: "eq_bool", interpreter: "eq_bool", lem: "eq", coq: "Bool.eqb", lean: "Eq", _: "eq_bool"} : (bool, bool) -> bool | |||
|
|||
val neq_int = pure {lem: "neq"} : forall 'n 'm. (int('n), int('m)) -> bool('n != 'm) | |||
val neq_int = pure {lem: "neq", lean: "¬ Eq"} : forall 'n 'm. (int('n), int('m)) -> bool('n != 'm) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use Ne
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, done
lib/vector.sail
Outdated
@@ -175,6 +175,7 @@ val bitvector_access = pure { | |||
interpreter: "access", | |||
lem: "access_vec_dec", | |||
coq: "access_vec_dec", | |||
lean: "vectorAccess", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... shouldn't bitvector access use a bitvector operation, like bv.getLsbD i
instead of a vecctor operation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, these edits weren't needed
lib/vector.sail
Outdated
@@ -183,6 +184,7 @@ val bitvector_access = pure { | |||
interpreter: "access_inc", | |||
lem: "access_vec_inc", | |||
coq: "access_vec_inc", | |||
lean: "vectorAccess", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
def GPRs : Vector (RegisterRef RegisterType (BitVec 64)) 31 := | ||
[Reg R30, Reg R29, Reg R28, Reg R27, Reg R26, Reg R25, Reg R24, Reg R23, Reg R22, Reg R21, Reg R20, | ||
Reg R19, Reg R18, Reg R17, Reg R16, Reg R15, Reg R14, Reg R13, Reg R12, Reg R11, Reg R10, Reg R9, | ||
Reg R8, Reg R7, Reg R6, Reg R5, Reg R4, Reg R3, Reg R2, Reg R1, Reg R0].toArray.toVector |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can use this for vector literals. #v[a, b, c]
but I haven't tried
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks that's better
FYI, I added this function and it worked fine!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me now!
|
||
val rX : reg_index -> bits(64) | ||
|
||
function rX(n) = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be good to have a test with else if
to exercise this part of the translation. Also, example with monadic things in the condition and in the branches (at least to see where we're at)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also do the whole if else
thing in a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added Leo's monad_test
function to register_vector.sail
and a separate ite.sail
test file for additional things.
| _ -> failwith ("Expression " ^ string_of_exp_con full_exp ^ " " ^ string_of_exp full_exp ^ " not translatable yet.") | ||
|
||
and doc_fexp with_arrow ctx (FE_aux (FE_fexp (field, e), _)) = | ||
doc_id_ctor field ^^ string " := " ^^ wrap_with_left_arrow with_arrow (doc_exp false ctx e) | ||
|
||
and if_exp (ctxt : context) (full_env : env) (full_typ : typ) (elseif : bool) (as_monadic : bool) c t e = | ||
let if_pp = string (if elseif then "else if" else "if") in | ||
let c_pp = doc_exp as_monadic ctxt c in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that's right. You need to check whether c
is monadic and use that as an argument to both the call of doc_exp
and then add a call to wrap_with_left_arrow
to pull the monadic value out in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I have locally as a minimal implementation, not thoroughly tested though:
| E_if (i, t, e) ->
let condition_monadic = effectful (effect_of i) in
nest 2 (string "if" ^^ space ^^ wrap_with_left_arrow condition_monadic (doc_exp condition_monadic ctx i)) ^^ hardline ^^
nest 2 (string "then" ^^ space ^^ doc_exp as_monadic ctx t) ^^ hardline ^^
nest 2 (string "else" ^^ space ^^ doc_exp as_monadic ctx e)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you're correct, I've changed it to something closer to your implementation
default := .Reg _PC | ||
|
||
def GPRs : Vector (RegisterRef RegisterType (BitVec 64)) 31 := | ||
#v[Reg R30, Reg R29, Reg R28, Reg R27, Reg R26, Reg R25, Reg R24, Reg R23, Reg R22, Reg R21, Reg R20, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
|
||
open Sail | ||
|
||
def reg_index := Nat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather have abbrev RegIndex := Nat
here. The def
instead of abbrev
will make the new type have no usable instances on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit out of the scope of this PR, but I have changed it
string "else" ^/^ doc_exp as_monadic ctxt (E_aux (E_internal_plet (pat, exp1, exp2), ann)) | ||
| _ -> prefix 2 1 (string "else") (doc_exp as_monadic ctxt e) | ||
in | ||
prefix 2 1 (soft_surround 2 1 if_pp c_pp (string "then")) t_pp ^^ break 1 ^^ else_pp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this copied over from the Coq printer? If so maybe mark it as such so we can improve it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it was, it's not here anymore, but I have marked the other part that was copied from the Coq printer
@@ -73,7 +73,7 @@ let opt_lean_output_dir : string option ref = ref None | |||
|
|||
let opt_lean_force_output : bool ref = ref false | |||
|
|||
let lean_version : string = "lean4:nightly-2024-09-25" | |||
let lean_version : string = "lean4:nightly-2025-01-22" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this bumped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was bumped because nightly-2024-09-25 used a different implementation of Vector
s
This also adds a test file for ite, and an additional test in register_vector
@@ -413,6 +418,14 @@ let rec doc_exp (as_monadic : bool) ctx (E_aux (e, (l, annot)) as full_exp) = | |||
| LE_deref e' -> string "writeRegRef " ^^ doc_exp false ctx e' ^^ space ^^ doc_exp false ctx e | |||
| _ -> failwith ("assign " ^ string_of_lexp le ^ "not implemented yet") | |||
) | |||
| E_if (i, t, e) -> | |||
let statements_monadic = as_monadic || effectful (effect_of t) || effectful (effect_of e) in | |||
nest 2 (string "if" ^^ space ^^ nest 1 (doc_exp false ctx i)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this still ignores the monadicity of the condition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But yes, let's ignore that for now and fix it when we need to fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does because the condition should never be monadic (it should be a Bool and not a SailM Bool), instead the responsibility is on doc_exp
, see line 352
The responsibility needs to be moved like that, because we want to be able to handle both if (Eq (← (rX r)) 0)
and if (← readReg B)
This also updates the lean version to have the recent updates to Vector, and adds
neq
andif then else
support to have proper access functions.