Skip to content

Commit fe7b7ff

Browse files
committed
Merge branch 'small-fix' into PointerADT
2 parents 2090913 + 8b621c8 commit fe7b7ff

File tree

9 files changed

+248
-51
lines changed

9 files changed

+248
-51
lines changed

.mill-jvm-opts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
-Xss32m
1+
-Xss128m
22
-Xmx2G

mill-build/util/src/util/JavaModule.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import scalalib.{JavaModule => BaseJavaModule}
66
trait JavaModule extends BaseJavaModule {
77
// https://github.com/viperproject/silicon/issues/748
88
// 32MB is enough stack space for silicon, a 100% marco guarantee
9-
override def forkArgs = Seq("-Xmx2G", "-Xss32m")
9+
override def forkArgs = Seq("-Xmx2G", "-Xss128m")
1010

1111
def classPathFileElements = T { runClasspath().map(_.path.toString) }
1212

res/universal/res/c/math.h

Lines changed: 198 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,226 @@
11
#ifndef MATH_H
22
#define MATH_H
33

4+
# define M_PI 3.14159265358979323846 /* pi */
5+
46
/*@
5-
ensures \result == (\is_int(x) ? x : (double)((int)x + 1));
67
decreases;
8+
pure double M_PI() = 3.14159265358979323846;
79
@*/
8-
double /*@ pure @*/ ceil(double x);
910

1011
/*@
11-
ensures \result == (x >= 0 ? x : -x);
12+
requires x>= 0;
13+
ensures \result == \pow(x, 0.5);
1214
decreases;
1315
@*/
14-
double /*@ pure @*/ fabs(double x);
16+
float /*@ pure @*/ sqrtf(float x);
17+
18+
/*@ ensures \result >= -1 && \result <= 1;
19+
decreases;
20+
@*/
21+
float /*@ pure @*/ sinf(float x);
1522

1623
/*@
17-
ensures \result == (double)((int)x);
24+
requires x >= -1 && x <= 1;
25+
ensures \result >= -M_PI()/2 && \result <= M_PI()/2;
1826
decreases;
1927
@*/
20-
double /*@ pure @*/ floor(double x);
28+
float /*@ pure @*/ asinf(float x);
29+
/*@
30+
ensures \result >= -1 && \result <= 1;
31+
decreases;
32+
@*/
33+
float /*@ pure @*/ cosf(float x);
34+
35+
/*@
36+
requires x >= -1 && x <= 1;
37+
ensures \result >= 0 && \result <= M_PI();
38+
decreases;
39+
@*/
40+
float /*@ pure @*/ acosf(float x);
41+
42+
/*@
43+
ensures x == 0 ==> \result == 0;
44+
decreases;
45+
@*/
46+
float /*@ pure @*/ tanf(float x);
47+
48+
/*@
49+
ensures \result >= -M_PI()/2 && \result <= M_PI()/2;
50+
decreases;
51+
@*/
52+
float /*@ pure @*/ atanf(float x);
53+
54+
/*@
55+
ensures -M_PI() <= \result && \result <= M_PI();
56+
decreases;
57+
@*/
58+
float /*@ pure @*/ atan2f(float x, float y);
59+
60+
/*@
61+
ensures \result == (expf(x) - expf(-x)) \ 2;
62+
decreases;
63+
@*/
64+
float /*@ pure @*/ sinhf(float x);
65+
66+
/*@
67+
ensures \result == (expf(x) + expf(-x)) \ 2;
68+
decreases;
69+
@*/
70+
float /*@ pure @*/ coshf(float x);
71+
72+
/*@
73+
ensures \result == (expf(x) - expf(-x)) \ (expf(x) + expf(-x));
74+
decreases;
75+
@*/
76+
float /*@ pure @*/ tanhf(float x);
77+
78+
/*@
79+
ensures \result == powf(x*x + y*y, 0.5);
80+
decreases;
81+
@*/
82+
float /*@ pure @*/ hypotf(float x, float y);
83+
84+
/*@
85+
ensures \result == powf(2.7182818284, x);
86+
decreases;
87+
@*/
88+
float /*@ pure @*/ expf(float x);
89+
90+
/*@
91+
decreases;
92+
@*/
93+
float /*@ pure @*/ logf(float x);
2194

2295
/*@
23-
// Gets replaced by internal SMT function in VerCors
2496
ensures \result == \pow(x, y);
97+
ensures x > 0 ==> \result > 0;
2598
decreases;
2699
@*/
27-
double /*@ pure @*/ pow(double x, double y);
100+
float /*@ pure @*/ powf(float x, float y);
28101

29102
/*@
30-
ensures \result == \pow(x, 0.5);
103+
ensures \result == (float)((int)x);
104+
decreases;
105+
@*/
106+
float /*@ pure @*/ floorf(float x);
107+
108+
/*@
109+
ensures \result == (\is_int(x) ? x : (float)((int)x + 1));
110+
decreases;
111+
@*/
112+
float /*@ pure @*/ ceilf(float x);
113+
114+
/*@
115+
ensures !(x < 0 && \is_int(x-0.5)) ==> \result == (float)(int)(x + 0.5);
116+
ensures (x < 0 && \is_int(x-0.5)) ==> \result == x-0.5;
117+
decreases;
118+
@*/
119+
float /*@ pure @*/ roundf(float x);
120+
121+
/*@
122+
requires x>= 0;
123+
ensures \result == pow(x, 0.5);
31124
decreases;
32125
@*/
33126
double /*@ pure @*/ sqrt(double x);
34127

128+
/*@ ensures \result >= -1 && \result <= 1;
129+
decreases;
130+
@*/
131+
double /*@ pure @*/ sin(double x);
132+
133+
/*@
134+
requires x >= -1 && x <= 1;
135+
ensures \result >= -M_PI()/2 && \result <= M_PI()/2;
136+
decreases;
137+
@*/
138+
double /*@ pure @*/ asin(double x);
139+
/*@
140+
ensures \result >= -1 && \result <= 1;
141+
decreases;
142+
@*/
143+
double /*@ pure @*/ cos(double x);
144+
145+
/*@
146+
requires x >= -1 && x <= 1;
147+
ensures \result >= 0 && \result <= M_PI();
148+
decreases;
149+
@*/
150+
double /*@ pure @*/ acos(double x);
151+
152+
/*@
153+
ensures x == 0 ==> \result == 0;
154+
decreases;
155+
@*/
156+
double /*@ pure @*/ tan(double x);
157+
158+
/*@
159+
ensures \result >= -M_PI()/2 && \result <= M_PI()/2;
160+
decreases;
161+
@*/
162+
double /*@ pure @*/ atan(double x);
163+
164+
/*@
165+
ensures -M_PI() <= \result && \result <= M_PI();
166+
decreases;
167+
@*/
168+
double /*@ pure @*/ atan2(double x, double y);
169+
170+
/*@
171+
//ensures \result == (exp(x) - exp(-x)) \ 2;
172+
decreases;
173+
@*/
174+
double /*@ pure @*/ sinh(double x);
175+
176+
/*@
177+
ensures \result == (exp(x) + exp(-x)) \ 2;
178+
decreases;
179+
@*/
180+
double /*@ pure @*/ cosh(double x);
181+
182+
/*@
183+
ensures \result == (exp(x) - exp(-x)) \ (exp(x) + exp(-x));
184+
decreases;
185+
@*/
186+
double /*@ pure @*/ tanh(double x);
187+
188+
/*@
189+
ensures \result == pow(x*x + y*y, 0.5);
190+
decreases;
191+
@*/
192+
double /*@ pure @*/ hypot(double x, double y);
193+
194+
/*@
195+
ensures \result == pow(2.7182818284, x);
196+
decreases;
197+
@*/
198+
double /*@ pure @*/ exp(double x);
199+
200+
/*@
201+
decreases;
202+
@*/
203+
double /*@ pure @*/ log(double x);
204+
205+
/*@
206+
ensures \result == \pow(x, y);
207+
ensures x > 0 ==> \result > 0;
208+
decreases;
209+
@*/
210+
double /*@ pure @*/ pow(double x, double y);
211+
212+
/*@
213+
ensures \result == (double)((int)x);
214+
decreases;
215+
@*/
216+
double /*@ pure @*/ floor(double x);
217+
218+
/*@
219+
ensures \result == (\is_int(x) ? x : (double)((int)x + 1));
220+
decreases;
221+
@*/
222+
double /*@ pure @*/ ceil(double x);
223+
35224
/*@
36225
ensures !(x < 0 && \is_int(x-0.5)) ==> \result == (double)(int)(x + 0.5);
37226
ensures (x < 0 && \is_int(x-0.5)) ==> \result == x-0.5;

src/col/vct/col/ast/type/typeclass/FloatTypeImpl.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import vct.col.ast.{CPrimitiveType, CSpecificationType, FloatType, TCFloat, TFlo
55
import vct.col.origin.{DiagnosticOrigin, Origin}
66
import vct.col.print.{Ctx, Doc, Text}
77
import vct.col.typerules.CoercionUtils
8+
import vct.col.resolve.lang.C
89

910
// https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_standard:_binary32
1011
// https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64
@@ -17,7 +18,9 @@ object TFloats {
1718

1819
// Only returns a float, when one of the types is floating itself
1920
// Returns to biggest float, e.g. (float32, float64) should return float64
20-
def getFloatMax[G](l: Type[G], r: Type[G]): Option[FloatType[G]] = {
21+
def getFloatMax[G](ll: Type[G], rr: Type[G]): Option[FloatType[G]] = {
22+
val l = C.stripCPrimitiveType(ll)
23+
val r = C.stripCPrimitiveType(rr)
2124
val promote = (l, r) match {
2225
case (_: TFloat[G], _) => true
2326
case (_, _: TFloat[G]) => true
@@ -29,9 +32,6 @@ object TFloats {
2932
}
3033

3134
(l, r) match {
32-
// Work for CPrimitive Types
33-
case (CPrimitiveType(Seq(CSpecificationType(innerL))), r) => getFloatMax(innerL, r)
34-
case (l, CPrimitiveType(Seq(CSpecificationType(innerR)))) => getFloatMax(l, innerR)
3535
case (l: FloatType[G], r: FloatType[G]) if r.exponent == l.exponent && r.mantissa == l.mantissa => Some(promoting(l))
3636
case (l: FloatType[G], r: FloatType[G]) if l.exponent < r.exponent && l.mantissa < r.mantissa => Some(promoting(r))
3737
case (l: FloatType[G], r: FloatType[G]) if r.exponent < l.exponent && r.mantissa < l.mantissa => Some(promoting(l))

src/col/vct/col/resolve/lang/C.scala

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,19 +120,25 @@ case object C {
120120
case target: RefCFunctionDefinition[G] if target.name == nameFromDeclarator(declarator) => target
121121
}
122122

123+
def stripCPrimitiveType[G](t: Type[G]): Type[G] = t match {
124+
case CPrimitiveType(specs) => getPrimitiveType(specs)
125+
case _ => t
126+
}
127+
128+
123129
def findPointerDeref[G](obj: Expr[G], name: String, ctx: ReferenceResolutionContext[G], blame: Blame[BuiltinError]): Option[CDerefTarget[G]] =
124-
obj.t match {
125-
case CPrimitiveType(Seq(CSpecificationType(CTPointer(innerType: TNotAValue[G])))) => innerType.decl.get match {
130+
stripCPrimitiveType(obj.t) match {
131+
case CTPointer(innerType: TNotAValue[G]) => innerType.decl.get match {
126132
case RefCStruct(decl) => getCStructDeref(decl, name)
127133
case _ => None
128134
}
129-
case CPrimitiveType(Seq(CSpecificationType(CTPointer(struct: CTStruct[G])))) =>
135+
case CTPointer(struct: CTStruct[G]) =>
130136
getCStructDeref(struct.ref.decl, name)
131-
case CPrimitiveType(Seq(CSpecificationType(CTArray(_, innerType: TNotAValue[G])))) => innerType.decl.get match {
137+
case CTArray(_, innerType: TNotAValue[G]) => innerType.decl.get match {
132138
case RefCStruct(decl) => getCStructDeref(decl, name)
133139
case _ => None
134140
}
135-
case CPrimitiveType(Seq(CSpecificationType(CTArray(_, struct: CTStruct[G])))) =>
141+
case CTArray(_, struct: CTStruct[G]) =>
136142
getCStructDeref(struct.ref.decl, name)
137143
case CTPointer(struct: CTStruct[G]) => getCStructDeref(struct.ref.decl, name)
138144
case CTArray(_, struct: CTStruct[G]) => getCStructDeref(struct.ref.decl, name)
@@ -149,16 +155,14 @@ case object C {
149155
}
150156

151157
def findDeref[G](obj: Expr[G], name: String, ctx: ReferenceResolutionContext[G], blame: Blame[BuiltinError]): Option[CDerefTarget[G]] =
152-
(obj.t match {
158+
(stripCPrimitiveType(obj.t) match {
153159
case t: TNotAValue[G] => t.decl.get match {
154160
case RefAxiomaticDataType(decl) => decl.decls.flatMap(Referrable.from).collectFirst {
155161
case ref: RefADTFunction[G] if ref.name == name => ref
156162
}
157163
case RefCStruct(decl: CGlobalDeclaration[G]) => getCStructDeref(decl, name)
158164
case _ => None
159165
}
160-
case CPrimitiveType(Seq(CSpecificationType(struct: CTStruct[G]))) =>
161-
getCStructDeref(struct.ref.decl, name)
162166
case struct: CTStruct[G] =>
163167
getCStructDeref(struct.ref.decl, name)
164168
case CTCudaVec() =>

src/rewrite/vct/rewrite/ExtractInlineQuantifierPatterns.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ case class ExtractInlineQuantifierPatterns[Pre <: Generation]() extends Rewriter
3333

3434
case class MakePattern(pattern: Pattern) extends Rewriter[Pre] {
3535
override val allScopes = outer.allScopes
36+
var inScale: Boolean = false
3637

3738
override def dispatch(e: Expr[Pre]): Expr[Post] = e match {
3839
// PB: don't add nodes here just to be conservative: in general all terms are allowable in patterns, *except*
3940
// that z3 disallows all Bool-related operators, and Viper additionally disallows all arithmetic operators. Any
4041
// other operators is necessarily encoded as an smt function (allowed), or banned due to being a side effect
4142
// (later dealt with rigorously).
43+
case e if inScale => e.rewriteDefault()
4244

4345
case And(_, _) | Or(_, _) | Implies(_, _) | Star(_, _) | Wand(_, _) | PolarityDependent(_, _) =>
4446
throw NotAllowedInTrigger(e)
@@ -56,6 +58,12 @@ case class ExtractInlineQuantifierPatterns[Pre <: Generation]() extends Rewriter
5658

5759
case Local(Ref(v)) if pattern.letBindingsHere.contains(v) => dispatch(pattern.letBindingsHere(v))
5860

61+
case p@PredicateApply(ref, args, perm) =>
62+
inScale = true
63+
val newPerm = dispatch(perm)
64+
inScale = false
65+
PredicateApply(succ[Predicate[Post]](ref.decl), args.map(dispatch), newPerm)(e.o)
66+
5967
case e => rewriteDefault(e)
6068
}
6169
}

src/rewrite/vct/rewrite/ResolveScale.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ case class ResolveScale[Pre <: Generation]() extends Rewriter[Pre] {
7171
case s: Starall[Pre] => s.rewrite(body = scale(s.body, amount))
7272

7373
case l: Let[Pre] => l.rewrite(main = scale(l.main, amount))
74-
74+
case InlinePattern(inner, parent, group) => InlinePattern(scale(inner, amount), parent, group)
7575
case other => throw WrongScale(other)
7676
}
7777
}

0 commit comments

Comments
 (0)