Skip to content

Commit cef5c50

Browse files
committed
Set up for a future mode /allocated:4 that also adds allocated antecedents for bound variables that are not already bounded by their types or range expressions.
1 parent db8722f commit cef5c50

File tree

6 files changed

+118
-34
lines changed

6 files changed

+118
-34
lines changed

Source/Dafny/DafnyAst.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,12 @@ private Expression ArrowSubtypeConstraint(IToken tok, BoundVar id, Function memb
276276
// forall x0,x1,x2 :: f.requires(x0,x1,x2)
277277
var bvs = new List<BoundVar>();
278278
var args = new List<Expression>();
279+
var bounds = new List<ComprehensionExpr.BoundedPool>();
279280
for (int i = 0; i < tps.Count - 1; i++) {
280281
var bv = new BoundVar(tok, "x" + i, new UserDefinedType(tps[i]));
281282
bvs.Add(bv);
282283
args.Add(new IdentifierExpr(tok, bv));
284+
bounds.Add(new ComprehensionExpr.SpecialAllocIndependenceAllocatedBoundedPool());
283285
}
284286
var fn = new MemberSelectExpr(tok, f, member.Name) {
285287
Member = member,
@@ -294,8 +296,7 @@ private Expression ArrowSubtypeConstraint(IToken tok, BoundVar id, Function memb
294296
body = Expression.CreateEq(body, emptySet, member.ResultType);
295297
}
296298
if (tps.Count > 1) {
297-
body = new ForallExpr(tok, bvs, null, body, null);
298-
body.Type = Type.Bool; // resolve here
299+
body = new ForallExpr(tok, bvs, null, body, null) { Type = Type.Bool, Bounds = bounds };
299300
}
300301
return body;
301302
}
@@ -9693,6 +9694,7 @@ public enum PoolVirtues { None = 0, Finite = 1, Enumerable = 2, IndependentOfAll
96939694
///
96949695
/// 0: AllocFreeBoundedPool
96959696
/// 0: ExplicitAllocatedBoundedPool
9697+
/// 0: SpecialAllocIndependenceAllocatedBoundedPool
96969698
///
96979699
/// 1: WiggleWaggleBound
96989700
///
@@ -9744,6 +9746,12 @@ public static List<VT> MissingBounds<VT>(List<VT> vars, List<BoundedPool> bounds
97449746
}
97459747
return missing;
97469748
}
9749+
public static List<bool> HasBounds(List<BoundedPool> bounds, PoolVirtues requiredVirtues = PoolVirtues.None) {
9750+
Contract.Requires(bounds != null);
9751+
Contract.Ensures(Contract.Result<List<bool>>() != null);
9752+
Contract.Ensures(Contract.Result<List<bool>>().Count == bounds.Count);
9753+
return bounds.ConvertAll(bound => bound != null && (bound.Virtues & requiredVirtues) == requiredVirtues);
9754+
}
97479755
static List<BoundedPool> CombineIntegerBounds(List<BoundedPool> bounds) {
97489756
var lowerBounds = new List<IntBoundedPool>();
97499757
var upperBounds = new List<IntBoundedPool>();
@@ -9816,6 +9824,13 @@ public ExplicitAllocatedBoundedPool() {
98169824
public override PoolVirtues Virtues => PoolVirtues.Finite | PoolVirtues.IndependentOfAlloc_or_ExplicitAlloc;
98179825
public override int Preference() => 0;
98189826
}
9827+
public class SpecialAllocIndependenceAllocatedBoundedPool : BoundedPool
9828+
{
9829+
public SpecialAllocIndependenceAllocatedBoundedPool() {
9830+
}
9831+
public override PoolVirtues Virtues => PoolVirtues.IndependentOfAlloc_or_ExplicitAlloc;
9832+
public override int Preference() => 0;
9833+
}
98199834
public class IntBoundedPool : BoundedPool
98209835
{
98219836
public readonly Expression LowerBound;

Source/Dafny/DafnyOptions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ protected override bool ParseOption(string name, Bpl.CommandLineOptionEngine.Com
302302
}
303303

304304
case "allocated": {
305-
ps.GetNumericArgument(ref Allocated, 4);
305+
ps.GetNumericArgument(ref Allocated, 5);
306306
return true;
307307
}
308308

@@ -559,6 +559,8 @@ than including DafnyRuntime.cs verbatim.
559559
even bound variables in quantifiers. This option is
560560
the easiest to use for heapful code.
561561
3 - (default) Frugal use of heap parameters.
562+
4 - mode 3 but with alloc antecedents when ranges don't imply
563+
allocatedness.
562564
/ironDafny Enable experimental features needed to support Ironclad/Ironfleet. Use of
563565
these features may cause your code to become incompatible with future
564566
releases of Dafny.

Source/Dafny/Rewriter.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ protected override bool VisitOneStmt(Statement stmt, ref bool st) {
111111
List<Expression> exprList = new List<Expression>();
112112
ForallExpr expr = new ForallExpr(s.Tok, s.BoundVars, s.Range, term, s.Attributes);
113113
expr.Type = Type.Bool; // resolve here
114+
expr.Bounds = s.Bounds;
114115
exprList.Add(expr);
115116
s.ForallExpressions = exprList;
116117
} else if (s.Kind == ForallStmt.BodyKind.Assign) {
@@ -191,6 +192,7 @@ protected override bool VisitOneStmt(Statement stmt, ref bool st) {
191192
if (!usedInversion) {
192193
var expr = new ForallExpr(s.Tok, s.BoundVars, s.Range, new BinaryExpr(s.Tok, BinaryExpr.ResolvedOpcode.EqCommon, lhs, rhs), s.Attributes);
193194
expr.Type = Type.Bool; // resolve here
195+
expr.Bounds = s.Bounds;
194196
exprList.Add(expr);
195197
}
196198
s.ForallExpressions = exprList;
@@ -212,6 +214,7 @@ protected override bool VisitOneStmt(Statement stmt, ref bool st) {
212214
List<Expression> exprList = new List<Expression>();
213215
ForallExpr expr = new ForallExpr(s.Tok, s.BoundVars, s.Range, term, s.Attributes);
214216
expr.Type = Type.Bool; // resolve here
217+
expr.Bounds = s.Bounds;
215218
exprList.Add(expr);
216219
s.ForallExpressions = exprList;
217220
} else {

0 commit comments

Comments
 (0)