Unfolding definitions after the fact #2556
-
Disclaimer: This is a question I asked on Slack and which involved @hacklex and got a terrific answer from @aseemr. Is there a way to mark function definitions as let foo = (* ... *) and then suddenly have it behave as if it was unfold let foo = (* ... *) An instance I am interested in is to take let n = 0
let m = 1
let foo = n + m and produce a new version of unfold let foo' = 0 + 1 Typically, I would prove things about |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Transcript from @aseemr's answer. F* has a module Test
open FStar.Tactics
[@@ "opaque_to_smt"]
let n = 0
[@@ "opaque_to_smt"]
let m = 1
let t () : Tac unit = norm [delta_only [`%n; `%m]]; trefl ()
[@@ (postprocess_with t)]
let foo = n + m
let test () = assert (foo == 1) The backtick followed by The same method can be used to make a definition module Test
open FStar.Tactics
[@@ "opaque_to_smt"]
let k = 0
let t () : Tac unit = norm [delta_only [`%k]]; trefl ()
[@@ (postprocess_with t)]
unfold
let k' = k
#set-options "--no_smt"
//With no smt, this proof relies on k' being unfolded in the typechecker
let test2 () = assert (k' == 0) |
Beta Was this translation helpful? Give feedback.
Transcript from @aseemr's answer.
F* has a
postprocess_with
attribute that lets one run a meta-program (tactic) on a definition after it has type-checked. It has to solve a goal of the forme == ?u
(wheree
is the body of the function), hence thetrefl
tactic at the end.The backtick followed by
%n
here quotesn
.The same method can be used to make a definition
unfold
after the fact: