-
I'm seeing z3 struggle with some proofs that seem like they should be trivial while succeeding with other proofs that don't semantically differ. In particular, this trivial lemma seems to be proven without needing to shoot off any queries to z3 (no file is created when using the let test_forall_int_lemma () : Lemma
(requires forall (x:int). False)
(ensures False)
= () However if I simply change the type of x from let test_forall_nat_lemma () : Lemma
(requires forall (x:nat). False)
(ensures False)
= () Even more oddly, z3 can prove the lemma if I make a trivial change, such as squashing a trivial nat equality using a variable: let two : nat = 2
// Note: The proof of test_forall_nat_lemma only succeeds when using the variable `two` rather than the value `2`
let two_equals_two : squash(2 == two) = ()
let test_forall_nat_lemma () : Lemma
(requires forall (x:nat). False)
(ensures False)
= () Does anyone know what's going on with these lemmas? I'm assuming that the first lemma can be trivially discharged by F* without needing to query z3 and that the second lemma needs to send queries to z3 since nat is a refined type, but why can the third lemma be trivially proven when the second lemma can't? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
For trivially inhabited types So, your first example becomes Your second example doesn't get simplified, so Z3 sees In the third example, the goal is still |
Beta Was this translation helpful? Give feedback.
For trivially inhabited types
t
(likeint
) F*'s simplifier simplifiesforall (x:t). False
toFalse
So, your first example becomes
False ==> False
, which F* proves without going to Z3.Your second example doesn't get simplified, so Z3 sees
(forall (x:nat). False) ==> False
, but to instantiate the quantifer in the hypothesis it needs to find a nat, which it can't do. In SMT2, this is roughly(implies (forall ((x Term)). (! (implies (HasType x nat) false) :pattern ((HasType x nat))) false)
, so Z3 needs to derive (HasType N nat) for someN
In the third example, the goal is still
(forall (x:nat). False) ==> False
, but now Z3 has in its context an assertion saying that(HasType two nat) /\ (= t…