Skip to content

Commit

Permalink
[Civl] Fixed bug in refinement check for actions (#853)
Browse files Browse the repository at this point in the history
The refinement check for actions was handling the frame condition
correctly. Now the frame condition is handled in the same manner as the
refinement check for procedures.

Co-authored-by: Shaz Qadeer <[email protected]>
  • Loading branch information
shazqadeer and Shaz Qadeer authored Mar 1, 2024
1 parent 9ae690e commit d7b1041
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 12 deletions.
2 changes: 0 additions & 2 deletions Source/Concurrency/CivlCoreTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ public Action(CivlTypeChecker civlTypeChecker, ActionDecl actionDecl, Action ref

public LayerRange LayerRange => ActionDecl.LayerRange;

public int LowerLayer => LayerRange.LowerLayer;

public IEnumerable<ActionDecl> PendingAsyncs => ActionDecl.CreateActionDecls;

public bool HasPendingAsyncs => PendingAsyncs.Any();
Expand Down
5 changes: 5 additions & 0 deletions Source/Concurrency/CivlTypeChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,11 @@ private void MatchFormals(List<Variable> formals1, List<Variable> formals2, stri

public IEnumerable<Variable> GlobalVariables => program.GlobalVariables;

public IEnumerable<Variable> GlobalVariablesAtLayer(int layerNum)
{
return GlobalVariables.Where(v => v.LayerRange.LowerLayer <= layerNum && layerNum < v.LayerRange.UpperLayer);
}

public IEnumerable<Action> MoverActions => actionDeclToAction.Keys
.Where(actionDecl => actionDecl.HasMoverType).Select(actionDecl => actionDeclToAction[actionDecl]);

Expand Down
7 changes: 4 additions & 3 deletions Source/Concurrency/InductiveSequentialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,11 @@ public InlineSequentialization(CivlTypeChecker civlTypeChecker, Action targetAct
}
var subst = Substituter.SubstitutionFromDictionary(map);
inlinedImpl.Proc.Requires = refinedAction.Gate.Select(g => new Requires(false, Substituter.Apply(subst, g.Expr))).ToList();
var frame = new HashSet<Variable>(civlTypeChecker.GlobalVariablesAtLayer(targetAction.LayerRange.UpperLayer));
inlinedImpl.Proc.Ensures = new List<Ensures>(new[]
{
new Ensures(false, Substituter.Apply(subst, refinedAction.GetTransitionRelation(civlTypeChecker, inlinedImpl.Proc.ModifiedVars.ToHashSet())),
$"Refinement check of {targetAction.Name} failed")
new Ensures(false, Substituter.Apply(subst, refinedAction.GetTransitionRelation(civlTypeChecker, frame)))
{ Description = new FailureOnlyDescription($"Refinement check of {targetAction.Name} failed") }
});
}

Expand Down Expand Up @@ -245,7 +246,7 @@ private List<Declaration> GenerateConclusionChecker()
cmds.Add(CmdHelper.CallCmd(invariantAction.Impl.Proc, invariantAction.Impl.InParams,
invariantAction.Impl.OutParams));
cmds.Add(CmdHelper.AssumeCmd(NoPendingAsyncs));
var frame = new HashSet<Variable>(refinedAction.ModifiedGlobalVars);
var frame = new HashSet<Variable>(civlTypeChecker.GlobalVariablesAtLayer(targetAction.LayerRange.UpperLayer));
cmds.Add(GetCheck(targetAction.tok, Substituter.Apply(subst, refinedAction.GetTransitionRelation(civlTypeChecker, frame)),
$"IS conclusion of {targetAction.Name} failed"));

Expand Down
9 changes: 2 additions & 7 deletions Source/Concurrency/RefinementInstrumentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,10 @@ public ActionRefinementInstrumentation(
this.tok = impl.tok;
this.oldGlobalMap = new Dictionary<Variable, Variable>();
var yieldProcedureDecl = (YieldProcedureDecl)originalImpl.Proc;
//ActionProc actionProc = civlTypeChecker.procToYieldingProc[originalImpl.Proc] as ActionProc;
this.layerNum = yieldProcedureDecl.Layer;
foreach (Variable v in civlTypeChecker.GlobalVariables)
foreach (Variable v in civlTypeChecker.GlobalVariablesAtLayer(layerNum))
{
var layerRange = v.LayerRange;
if (layerRange.LowerLayer <= layerNum && layerNum < layerRange.UpperLayer)
{
this.oldGlobalMap[v] = oldGlobalMap[v];
}
this.oldGlobalMap[v] = oldGlobalMap[v];
}

this.newLocalVars = new List<Variable>();
Expand Down
25 changes: 25 additions & 0 deletions Test/civl/async/simple-fail.bpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %parallel-boogie "%s" > "%t"
// RUN: %diff "%s.expect" "%t"

var {:layer 0,2} x: int;
var {:layer 0,2} y: int;

atomic action {:layer 1} A()
modifies x, y;
refines B;
{
x := x + 1;
call X();
}

action {:layer 1} X()
modifies y;
{
y := y + 1;
}

atomic action {:layer 2} B()
modifies x;
{
havoc x;
}
6 changes: 6 additions & 0 deletions Test/civl/async/simple-fail.bpl.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
simple-fail.bpl(13,1): Error: a postcondition could not be proved on this return path
(0,0): Related location: Refinement check of A failed
Execution trace:
simple-fail.bpl(11,7): anon0

Boogie program verifier finished with 0 verified, 1 error
25 changes: 25 additions & 0 deletions Test/civl/async/simple.bpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %parallel-boogie "%s" > "%t"
// RUN: %diff "%s.expect" "%t"

var {:layer 0,2} x: int;
var {:layer 0,1} y: int;

atomic action {:layer 1} A()
modifies x, y;
refines B;
{
x := x + 1;
call X();
}

action {:layer 1} X()
modifies y;
{
y := y + 1;
}

atomic action {:layer 2} B()
modifies x;
{
havoc x;
}
2 changes: 2 additions & 0 deletions Test/civl/async/simple.bpl.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

Boogie program verifier finished with 1 verified, 0 errors

0 comments on commit d7b1041

Please sign in to comment.