Skip to content

Commit ae8708c

Browse files
authored
Chore: Proofs not depending on leaks of opaque + brittleness reduction (#149)
* Chore: Proofs not depending on leaks of opaque + brittleness reduction I added reveal statements where they were previously "leaked" because of fuel encoding that are soon going away. I also reduced the RU for ToLarge from 6.8M to 1.3M. * Forgot to save a file * Fixed brittleness issue for current Dafny * Fixed two brittle proofs * Fixed formatting * Comment about the proof * Update src/Collections/Sequences/LittleEndianNatConversions.dfy
1 parent 5d89343 commit ae8708c

File tree

8 files changed

+77
-12
lines changed

8 files changed

+77
-12
lines changed

src/Collections/Sequences/LittleEndianNatConversions.dfy

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,39 @@ abstract module {:options "-functionSyntax:4"} LittleEndianNatConversions {
8181
requires |xs| % E() == 0
8282
ensures |ys| == |xs| / E()
8383
{
84-
if |xs| == 0 then LemmaDivBasicsAuto(); []
84+
if |xs| == 0 then
85+
var ys := (LemmaDivBasicsAuto(); []);
86+
assert |ys| == |xs| / E();
87+
ys
88+
8589
else
8690
LemmaModIsZero(|xs|, E());
8791
assert |xs| >= E();
88-
8992
Small.LemmaSeqNatBound(xs[..E()]);
90-
LemmaModSubMultiplesVanishAuto();
9193
LemmaDivMinusOne(|xs|, E());
92-
[Small.ToNatRight(xs[..E()]) as Large.uint] + ToLarge(xs[E()..])
94+
assert |xs[E()..]| % E() == 0 by {
95+
LemmaModSubMultiplesVanishAuto();
96+
}
97+
var ys := ([Small.ToNatRight(xs[..E()]) as Large.uint] + ToLarge(xs[E()..]));
98+
assert |ToLarge(xs[E()..])| == |xs[E()..]| / E();
99+
assert |ys| == |xs| / E() by {
100+
// To obtain a proof like this, first write a detailed proof
101+
// as much as you can, not assuming anything about non-linear arithmetic (use only lemmas for that)
102+
// Then remove intermediate computation steps and lemma calls if doing so decrease the resource count
103+
// until arriving at at a minimum
104+
calc {
105+
|ys|;
106+
1 + |xs[E()..]| / E();
107+
1 + (|xs| - E()) / E();
108+
{ DivMod.ModINL.LemmaFundamentalDivMod(|xs|, E()); }
109+
1 + (E() * (|xs| / E()) + |xs| % E() - E()) / E();
110+
1 + (E() * (|xs| / E()) - E()) / E();
111+
1 + (E() * (|xs| / E()) + E() * -1) / E();
112+
{ Mul.LemmaMulIsDistributiveAdd(E(), |xs| / E(), -1); }
113+
1 + (E() * (|xs| / E() + -1)) / E();
114+
}
115+
}
116+
ys
93117
}
94118

95119
/* Sequence conversion from Large.BASE() to Small.BASE() does not

src/NonlinearArithmetic/DivMod.dfy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ module {:options "-functionSyntax:4"} DivMod {
3535
requires 0 < d
3636
ensures DivRecursive(x, d) == x / d
3737
{
38+
reveal DivPos();
3839
reveal DivRecursive();
3940
LemmaDivInductionAuto(d, x, u => DivRecursive(u, d) == u / d);
4041
}
4142

4243
lemma LemmaDivIsDivRecursiveAuto()
4344
ensures forall x: int, d: int {:trigger x / d} :: d > 0 ==> DivRecursive(x, d) == x / d
4445
{
46+
reveal DivPos();
4547
reveal DivRecursive();
4648
forall x: int, d: int | d > 0
4749
ensures DivRecursive(x, d) == x / d
@@ -136,6 +138,7 @@ module {:options "-functionSyntax:4"} DivMod {
136138
ensures x / y >= x / z
137139
decreases x
138140
{
141+
reveal DivPos();
139142
reveal DivRecursive();
140143
LemmaDivIsDivRecursiveAuto();
141144
assert forall u: int, d: int {:trigger u / d} {:trigger DivRecursive(u, d)}

src/NonlinearArithmetic/Logarithm.dfy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ module {:options "-functionSyntax:4"} Logarithm {
8585
Log(base, base * Pow(base, n - 1));
8686
{ LemmaPowPositive(base, n - 1);
8787
LemmaMulIncreases(Pow(base, n - 1), base);
88+
LemmaMulIsCommutative(Pow(base, n - 1), base);
8889
LemmaLogS(base, base * Pow(base, n - 1)); }
8990
1 + Log(base, (base * Pow(base, n - 1)) / base);
9091
{ LemmaDivMultiplesVanish(Pow(base, n - 1), base); }

src/NonlinearArithmetic/Power.dfy

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,23 +372,34 @@ module {:options "-functionSyntax:4"} Power {
372372
requires e1 < e2
373373
ensures Pow(b, e1) < Pow(b, e2)
374374
{
375+
reveal Pow();
375376
LemmaPowAuto();
376377
var f := e => 0 < e ==> Pow(b, e1) < Pow(b, e1 + e);
377378
forall i {:trigger IsLe(0, i)} | IsLe(0, i) && f(i)
378379
ensures f(i + 1)
379380
{
381+
assert 0 < i ==> Pow(b, e1) < Pow(b, e1 + i);
380382
calc {
381-
Pow(b, e1 + i);
383+
Pow(b, e1 + i);
382384
<= { LemmaPowPositive(b, e1 + i);
383385
LemmaMulLeftInequality(Pow(b, e1 + i), 1, b); }
384-
Pow(b, e1 + i) * b;
386+
Pow(b, e1 + i) * b;
385387
== { LemmaPow1(b); }
386-
Pow(b, e1 + i) * Pow(b, 1);
388+
Pow(b, e1 + i) * Pow(b, 1);
387389
== { LemmaPowAdds(b, e1 + i, 1); }
388-
Pow(b, e1 + i + 1);
390+
Pow(b, e1 + i + 1);
391+
== calc {
392+
e1 + i + 1;
393+
e1 + (i + 1);
394+
}
395+
Pow(b, e1 + (i + 1));
389396
}
397+
assert f(i+1);
390398
}
391399
LemmaMulInductionAuto(e2 - e1, f);
400+
assert Pow(b, e1) < Pow(b, e1 + (e2 - e1)) == Pow(b, e2) by {
401+
assert 0 < e2 - e1;
402+
}
392403
}
393404

394405
lemma LemmaPowStrictlyIncreasesAuto()
@@ -410,6 +421,7 @@ module {:options "-functionSyntax:4"} Power {
410421
requires e1 <= e2
411422
ensures Pow(b, e1) <= Pow(b, e2)
412423
{
424+
reveal Pow();
413425
LemmaPowAuto();
414426
var f := e => 0 <= e ==> Pow(b, e1) <= Pow(b, e1 + e);
415427
forall i {:trigger IsLe(0, i)} | IsLe(0, i) && f(i)
@@ -427,6 +439,9 @@ module {:options "-functionSyntax:4"} Power {
427439
}
428440
}
429441
LemmaMulInductionAuto(e2 - e1, f);
442+
assert Pow(b, e1) <= Pow(b, e1 + (e2 - e1)) by {
443+
assert 0 <= e2 - e1;
444+
}
430445
}
431446

432447
lemma LemmaPowIncreasesAuto()

src/NonlinearArithmetic/Power2.dfy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module {:options "-functionSyntax:4"} Power2 {
6060
requires 0 < e
6161
ensures (Pow2(e) - 1) / 2 == Pow2(e - 1) - 1
6262
{
63+
LemmaPow2Auto();
6364
LemmaPowAuto();
6465
var f := e => 0 < e ==> (Pow2(e) - 1) / 2 == Pow2(e - 1) - 1;
6566
assert forall i {:trigger IsLe(0, i)} :: IsLe(0, i) && f(i) ==> f(i + 1);
@@ -116,6 +117,7 @@ module {:options "-functionSyntax:4"} Power2 {
116117
ensures Pow2(64) == 0x10000000000000000
117118
{
118119
reveal Pow2();
120+
reveal Pow();
119121
}
120122

121123
}

src/dafny/NonlinearArithmetic/DivMod.dfy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module {:options "-functionSyntax:4"} Dafny.DivMod {
3636
requires 0 < d
3737
ensures DivRecursive(x, d) == x / d
3838
{
39+
reveal DivPos();
3940
reveal DivRecursive();
4041
LemmaDivInductionAuto(d, x, u => DivRecursive(u, d) == u / d);
4142
}
@@ -121,6 +122,7 @@ module {:options "-functionSyntax:4"} Dafny.DivMod {
121122
ensures x / y >= x / z
122123
decreases x
123124
{
125+
reveal DivPos();
124126
reveal DivRecursive();
125127
LemmaDivIsDivRecursiveAuto();
126128
assert forall u: int, d: int {:trigger u / d} {:trigger DivRecursive(u, d)}

src/dafny/NonlinearArithmetic/Power.dfy

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ module {:options "-functionSyntax:4"} Dafny.Power {
143143
ensures 0 < Pow(b, e)
144144
{
145145
LemmaMulIncreasesAuto();
146+
reveal Pow();
146147
LemmaMulInductionAuto(e, u => 0 <= u ==> 0 < Pow(b, u));
147148
}
148149

@@ -372,23 +373,34 @@ module {:options "-functionSyntax:4"} Dafny.Power {
372373
requires e1 < e2
373374
ensures Pow(b, e1) < Pow(b, e2)
374375
{
376+
reveal Pow();
375377
LemmaPowAuto();
376378
var f := e => 0 < e ==> Pow(b, e1) < Pow(b, e1 + e);
377379
forall i {:trigger IsLe(0, i)} | IsLe(0, i) && f(i)
378380
ensures f(i + 1)
379381
{
382+
assert 0 < i ==> Pow(b, e1) < Pow(b, e1 + i);
380383
calc {
381-
Pow(b, e1 + i);
384+
Pow(b, e1 + i);
382385
<= { LemmaPowPositive(b, e1 + i);
383386
LemmaMulLeftInequality(Pow(b, e1 + i), 1, b); }
384-
Pow(b, e1 + i) * b;
387+
Pow(b, e1 + i) * b;
385388
== { LemmaPow1(b); }
386-
Pow(b, e1 + i) * Pow(b, 1);
389+
Pow(b, e1 + i) * Pow(b, 1);
387390
== { LemmaPowAdds(b, e1 + i, 1); }
388-
Pow(b, e1 + i + 1);
391+
Pow(b, e1 + i + 1);
392+
== calc {
393+
e1 + i + 1;
394+
e1 + (i + 1);
395+
}
396+
Pow(b, e1 + (i + 1));
389397
}
398+
assert f(i+1);
390399
}
391400
LemmaMulInductionAuto(e2 - e1, f);
401+
assert Pow(b, e1) < Pow(b, e1 + (e2 - e1)) == Pow(b, e2) by {
402+
assert 0 < e2 - e1;
403+
}
392404
}
393405

394406
lemma LemmaPowStrictlyIncreasesAuto()
@@ -410,6 +422,7 @@ module {:options "-functionSyntax:4"} Dafny.Power {
410422
requires e1 <= e2
411423
ensures Pow(b, e1) <= Pow(b, e2)
412424
{
425+
reveal Pow();
413426
LemmaPowAuto();
414427
var f := e => 0 <= e ==> Pow(b, e1) <= Pow(b, e1 + e);
415428
forall i {:trigger IsLe(0, i)} | IsLe(0, i) && f(i)
@@ -427,6 +440,9 @@ module {:options "-functionSyntax:4"} Dafny.Power {
427440
}
428441
}
429442
LemmaMulInductionAuto(e2 - e1, f);
443+
assert Pow(b, e1) <= Pow(b, e1 + (e2 - e1)) by {
444+
assert 0 <= e2 - e1;
445+
}
430446
}
431447

432448
lemma LemmaPowIncreasesAuto()

src/dafny/NonlinearArithmetic/Power2.dfy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module {:options "-functionSyntax:4"} Dafny.Power2 {
6060
requires 0 < e
6161
ensures (Pow2(e) - 1) / 2 == Pow2(e - 1) - 1
6262
{
63+
LemmaPow2Auto();
6364
LemmaPowAuto();
6465
var f := e => 0 < e ==> (Pow2(e) - 1) / 2 == Pow2(e - 1) - 1;
6566
assert forall i {:trigger IsLe(0, i)} :: IsLe(0, i) && f(i) ==> f(i + 1);
@@ -115,6 +116,7 @@ module {:options "-functionSyntax:4"} Dafny.Power2 {
115116
ensures Pow2(32) == 0x100000000
116117
ensures Pow2(64) == 0x10000000000000000
117118
{
119+
reveal Pow();
118120
reveal Pow2();
119121
}
120122

0 commit comments

Comments
 (0)