public static Expr Refinement(AtomicActionCopy action, HashSet <Variable> frame) { return(ComputeTransitionRelation( new AtomicActionCopyAdapter(action, AtomicActionCopyKind.NORMAL), null, frame, null, false, string.Format("Transition relation of {0}", action.proc.Name))); }
public static Expr Nonblocking(AtomicActionCopy action, HashSet <Variable> frame) { return(ComputeTransitionRelation( new AtomicActionCopyAdapter(action, AtomicActionCopyKind.NORMAL), null, frame, null, true, string.Format("Nonblocking expression of {0}", action.proc.Name))); }
public static Expr Commutativity(AtomicActionCopy first, AtomicActionCopy second, HashSet <Variable> frame, List <WitnessFunction> witnesses) { return(ComputeTransitionRelation( new AtomicActionCopyAdapter(first, AtomicActionCopyKind.SECOND), new AtomicActionCopyAdapter(second, AtomicActionCopyKind.FIRST), frame, witnesses, false, string.Format("Transition relation of {0} ∘ {1}", first.proc.Name, second.proc.Name))); }
private Expr GetTransitionRelation(AtomicActionCopy atomicActionCopy) { if (!transitionRelationCache.ContainsKey(atomicActionCopy)) { transitionRelationCache[atomicActionCopy] = TransitionRelationComputation. Refinement(atomicActionCopy, new HashSet <Variable>(this.oldGlobalMap.Keys)); } return(transitionRelationCache[atomicActionCopy]); }
private static List <Block> ComposeBlocks(AtomicActionCopy first, AtomicActionCopy second) { List <Block> firstBlocks = CloneBlocks(first.firstAction.Blocks); List <Block> secondBlocks = CloneBlocks(second.secondAction.Blocks); foreach (Block b in firstBlocks.Where(b => b.TransferCmd is ReturnCmd)) { List <Block> bs = new List <Block> { secondBlocks[0] }; List <string> ls = new List <string> { secondBlocks[0].Label }; b.TransferCmd = new GotoCmd(b.tok, ls, bs); } return(Enumerable.Union(firstBlocks, secondBlocks).ToList()); }
private void CreateFailurePreservationChecker(AtomicActionCopy first, AtomicActionCopy second) { if (first.gateUsedGlobalVars.Intersect(second.modifiedGlobalVars).Count() == 0) { return; } if (!failurePreservationCheckerCache.Add(Tuple.Create(first, second))) { return; } List <Variable> inputs = Enumerable.Union(first.firstInParams, second.secondInParams).ToList(); List <Variable> outputs = Enumerable.Union(first.firstOutParams, second.secondOutParams).ToList(); List <Variable> locals = new List <Variable>(second.secondAction.LocVars); List <Block> blocks = CloneBlocks(second.secondAction.Blocks); HashSet <Variable> frame = new HashSet <Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List <Requires> requires = new List <Requires>(); requires.Add(DisjointnessRequires(first.firstInParams.Union(second.secondInParams).Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame)); Expr firstNegatedGate = Expr.Not(Expr.And(first.firstGate.Select(a => a.Expr))); firstNegatedGate.Type = Type.Bool; // necessary? requires.Add(new Requires(false, firstNegatedGate)); foreach (AssertCmd assertCmd in second.secondGate) { requires.Add(new Requires(false, assertCmd.Expr)); } IEnumerable <Expr> linearityAssumes = DisjointnessExpr(first.firstInParams.Union(second.secondOutParams), frame); Ensures ensureCheck = new Ensures(first.proc.tok, false, Expr.Imp(Expr.And(linearityAssumes), firstNegatedGate), null); ensureCheck.ErrorData = string.Format("Gate failure of {0} not preserved by {1}", first.proc.Name, second.proc.Name); List <Ensures> ensures = new List <Ensures> { ensureCheck }; string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name); AddChecker(checkerName, inputs, outputs, locals, requires, ensures, blocks); }
public TransitionRelationComputation(AtomicActionCopy first, AtomicActionCopy second, HashSet <Variable> frame, HashSet <Variable> postExistVars) { this.first = first; this.second = second; this.postExistVars = postExistVars; this.frame = frame; this.existsVars = new Dictionary <Variable, Variable>(); this.firstExistsVars = new HashSet <Variable>( first != null ? first.firstOutParams.Union(first.firstAction.LocVars) : Enumerable.Empty <Variable>()); this.secondExistsVars = new HashSet <Variable>(second.secondOutParams.Union(second.secondAction.LocVars)); this.cmdStack = new Stack <Cmd>(); this.paths = new List <PathInfo>(); EnumeratePaths(); }
private void CreateNonBlockingChecker(AtomicActionCopy second) { if (!second.HasAssumeCmd) { return; } List <Variable> inputs = new List <Variable>(second.secondInParams); List <Variable> outputs = new List <Variable>(); List <Variable> locals = new List <Variable>(); HashSet <Variable> frame = new HashSet <Variable>(); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List <Requires> requires = new List <Requires>(); requires.Add(DisjointnessRequires(second.secondInParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame)); foreach (AssertCmd assertCmd in second.secondGate) { requires.Add(new Requires(false, assertCmd.Expr)); } List <Ensures> ensures = new List <Ensures>(); HashSet <Variable> postExistVars = new HashSet <Variable>(); postExistVars.UnionWith(frame); postExistVars.UnionWith(second.secondOutParams); Expr nonBlockingExpr = (new TransitionRelationComputation(second, frame, postExistVars)).TransitionRelationCompute(); AssertCmd nonBlockingAssert = new AssertCmd(second.proc.tok, nonBlockingExpr); nonBlockingAssert.ErrorData = string.Format("Non-blocking check for {0} failed", second.proc.Name); List <Block> blocks = new List <Block> { new Block(second.proc.tok, "L", new List <Cmd>() { nonBlockingAssert }, new ReturnCmd(Token.NoToken)) }; string checkerName = string.Format("NonBlockingChecker_{0}", second.proc.Name); AddChecker(checkerName, inputs, outputs, locals, requires, ensures, blocks); }
private void CreateNonBlockingChecker(AtomicActionCopy action) { if (!action.HasAssumeCmd) { return; } string checkerName = $"NonBlockingChecker_{action.proc.Name}"; Implementation impl = action.impl; HashSet <Variable> frame = new HashSet <Variable>(); frame.UnionWith(action.gateUsedGlobalVars); frame.UnionWith(action.actionUsedGlobalVars); List <Requires> requires = new List <Requires> { DisjointnessRequires(impl.InParams. Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame) }; foreach (AssertCmd assertCmd in action.gate) { requires.Add(new Requires(false, assertCmd.Expr)); } Expr nonBlockingExpr = TransitionRelationComputation. Nonblocking(action, frame); AssertCmd nonBlockingAssert = new AssertCmd(action.proc.tok, nonBlockingExpr) { ErrorData = $"Non-blocking check for {action.proc.Name} failed" }; Block block = new Block(action.proc.tok, "L", new List <Cmd> { nonBlockingAssert }, new ReturnCmd(Token.NoToken)); AddChecker(checkerName, new List <Variable>(impl.InParams), new List <Variable>(), new List <Variable>(), requires, new List <Ensures>(), new List <Block> { block }); }
public TransitionRelationComputation(AtomicActionCopy second, HashSet <Variable> frame, HashSet <Variable> postExistVars) : this(null, second, frame, postExistVars) { }
public AtomicActionCopyAdapter(AtomicActionCopy action, AtomicActionCopyKind copyType) { this.action = action; this.copyType = copyType; }
private void CreateCommutativityChecker(AtomicActionCopy first, AtomicActionCopy second) { if (first == second && first.firstInParams.Count == 0 && first.firstOutParams.Count == 0) { return; } if (first.TriviallyCommutesWith(second)) { return; } if (!commutativityCheckerCache.Add(Tuple.Create(first, second))) { return; } List <Variable> inputs = Enumerable.Union(first.firstInParams, second.secondInParams).ToList(); List <Variable> outputs = Enumerable.Union(first.firstOutParams, second.secondOutParams).ToList(); List <Variable> locals = Enumerable.Union(first.firstAction.LocVars, second.secondAction.LocVars).ToList(); List <Block> blocks = ComposeBlocks(first, second); HashSet <Variable> frame = new HashSet <Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(first.actionUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List <Requires> requires = new List <Requires>(); requires.Add(DisjointnessRequires(first.firstInParams.Union(second.secondInParams).Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame)); foreach (AssertCmd assertCmd in Enumerable.Union(first.firstGate, second.secondGate)) { requires.Add(new Requires(false, assertCmd.Expr)); } var transitionRelationComputation = new TransitionRelationComputation(first, second, frame, new HashSet <Variable>()); Expr transitionRelation = transitionRelationComputation.TransitionRelationCompute(); { List <Block> bs = new List <Block> { blocks[0] }; List <string> ls = new List <string> { blocks[0].Label }; var initBlock = new Block(Token.NoToken, string.Format("{0}_{1}_init", first.proc.Name, second.proc.Name), transitionRelationComputation.TriggerAssumes(), new GotoCmd(Token.NoToken, ls, bs)); blocks.Insert(0, initBlock); } var secondInParamsFiltered = second.secondInParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN); IEnumerable <Expr> linearityAssumes = Enumerable.Union( DisjointnessExpr(first.firstOutParams.Union(secondInParamsFiltered), frame), DisjointnessExpr(first.firstOutParams.Union(second.secondOutParams), frame)); // TODO: add further disjointness expressions? Ensures ensureCheck = new Ensures(first.proc.tok, false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation), null); ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name); List <Ensures> ensures = new List <Ensures> { ensureCheck }; string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name); AddChecker(checkerName, inputs, outputs, locals, requires, ensures, blocks); }
public SomeRefinementInstrumentation( CivlTypeChecker civlTypeChecker, Implementation impl, Procedure originalProc, Dictionary <Variable, Variable> oldGlobalMap, HashSet <Block> yieldingLoopHeaders) { newLocalVars = new List <Variable>(); YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[originalProc]; int layerNum = yieldingProc.upperLayer; pc = Pc(); newLocalVars.Add(pc); ok = Ok(); newLocalVars.Add(ok); this.transitionRelationCache = new Dictionary <AtomicActionCopy, Expr>(); this.oldGlobalMap = new Dictionary <Variable, Variable>(); foreach (Variable v in civlTypeChecker.sharedVariables) { var layerRange = civlTypeChecker.GlobalVariableLayerRange(v); if (layerRange.lowerLayerNum <= yieldingProc.upperLayer && yieldingProc.upperLayer < layerRange.upperLayerNum) { this.oldGlobalMap[v] = oldGlobalMap[v]; } } Dictionary <Variable, Expr> foroldMap = new Dictionary <Variable, Expr>(); foreach (Variable g in civlTypeChecker.sharedVariables) { foroldMap[g] = Expr.Ident(oldGlobalMap[g]); } if (yieldingProc is ActionProc actionProc) { // The parameters of an atomic action come from the implementation that denotes the atomic action specification. // To use the transition relation computed below in the context of the yielding procedure of the refinement check, // we need to substitute the parameters. AtomicActionCopy atomicActionCopy = actionProc.refinedAction.layerToActionCopy[layerNum + 1]; Implementation atomicActionImpl = atomicActionCopy.impl; Dictionary <Variable, Expr> alwaysMap = new Dictionary <Variable, Expr>(); for (int i = 0; i < atomicActionImpl.InParams.Count; i++) { alwaysMap[atomicActionImpl.InParams[i]] = Expr.Ident(impl.InParams[i]); } for (int i = 0; i < atomicActionImpl.OutParams.Count; i++) { alwaysMap[atomicActionImpl.OutParams[i]] = Expr.Ident(impl.OutParams[i]); } Substitution always = Substituter.SubstitutionFromHashtable(alwaysMap); Substitution forold = Substituter.SubstitutionFromHashtable(foroldMap); Expr betaExpr = GetTransitionRelation(atomicActionCopy); beta = Substituter.ApplyReplacingOldExprs(always, forold, betaExpr); Expr alphaExpr = Expr.And(atomicActionCopy.gate.Select(g => g.Expr)); alphaExpr.Type = Type.Bool; alpha = Substituter.Apply(always, alphaExpr); } else { beta = Expr.And(this.oldGlobalMap.Keys.Select(v => Expr.Eq(Expr.Ident(v), foroldMap[v]))); alpha = Expr.True; } oldOutputMap = new Dictionary <Variable, Variable>(); foreach (Variable f in impl.OutParams) { LocalVariable copy = Old(f); newLocalVars.Add(copy); this.oldOutputMap[f] = copy; } pcsForYieldingLoopsHeaders = new Dictionary <Block, Variable>(); oksForYieldingLoopHeaders = new Dictionary <Block, Variable>(); foreach (Block header in yieldingLoopHeaders) { var pcForYieldingLoopHeader = PcForYieldingLoopHeader(header); newLocalVars.Add(pcForYieldingLoopHeader); pcsForYieldingLoopsHeaders[header] = pcForYieldingLoopHeader; var okForYieldingLoopHeader = OkForYieldingLoopHeader(header); newLocalVars.Add(okForYieldingLoopHeader); oksForYieldingLoopHeaders[header] = okForYieldingLoopHeader; } }
private void CreateFailurePreservationChecker(AtomicActionCopy first, AtomicActionCopy second) { if (!first.gateUsedGlobalVars.Intersect(second.modifiedGlobalVars).Any()) { return; } if (!failurePreservationCheckerCache.Add(Tuple.Create(first, second))) { return; } HashSet <Variable> frame = new HashSet <Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List <Requires> requires = new List <Requires> { DisjointnessRequires(first.firstInParams.Union(second.secondInParams).Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame) }; Expr firstNegatedGate = Expr.Not(Expr.And(first.firstGate.Select(a => a.Expr))); firstNegatedGate.Type = Type.Bool; // necessary? requires.Add(new Requires(false, firstNegatedGate)); foreach (AssertCmd assertCmd in second.secondGate) { requires.Add(new Requires(false, assertCmd.Expr)); } IEnumerable <Expr> linearityAssumes = DisjointnessExpr(first.firstInParams.Union(second.secondOutParams), frame); Ensures ensureCheck = new Ensures(first.proc.tok, false, Expr.Imp(Expr.And(linearityAssumes), firstNegatedGate), null) { ErrorData = $"Gate failure of {first.proc.Name} not preserved by {second.proc.Name}" }; List <Ensures> ensures = new List <Ensures> { ensureCheck }; string checkerName = $"FailurePreservationChecker_{first.proc.Name}_{second.proc.Name}"; List <Variable> inputs = Enumerable.Union(first.firstInParams, second.secondInParams).ToList(); List <Variable> outputs = Enumerable.Union(first.firstOutParams, second.secondOutParams).ToList(); var block = new Block(Token.NoToken, "init", new List <Cmd> { new CallCmd(Token.NoToken, second.proc.Name, second.secondInParams.Select(Expr.Ident).ToList <Expr>(), second.secondOutParams.Select(Expr.Ident).ToList() ) { Proc = second.proc } }, new ReturnCmd(Token.NoToken)); AddChecker(checkerName, inputs, outputs, new List <Variable>(), requires, ensures, new List <Block> { block }); }
private void CreateCommutativityChecker(AtomicActionCopy first, AtomicActionCopy second) { if (first == second && first.firstInParams.Count == 0 && first.firstOutParams.Count == 0) { return; } if (first.TriviallyCommutesWith(second)) { return; } if (!commutativityCheckerCache.Add(Tuple.Create(first, second))) { return; } string checkerName = $"CommutativityChecker_{first.proc.Name}_{second.proc.Name}"; HashSet <Variable> frame = new HashSet <Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(first.actionUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List <Requires> requires = new List <Requires> { DisjointnessRequires( first.firstInParams. Union(second.secondInParams). Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame) }; foreach (AssertCmd assertCmd in Enumerable.Union(first.firstGate, second.secondGate)) { requires.Add(new Requires(false, assertCmd.Expr)); } civlTypeChecker.atomicActionPairToWitnessFunctions.TryGetValue( Tuple.Create(first, second), out List <WitnessFunction> witnesses); var transitionRelation = TransitionRelationComputation. Commutativity(second, first, frame, witnesses); List <Cmd> cmds = new List <Cmd> { new CallCmd(Token.NoToken, first.proc.Name, first.firstInParams.Select(Expr.Ident).ToList <Expr>(), first.firstOutParams.Select(Expr.Ident).ToList() ) { Proc = first.proc }, new CallCmd(Token.NoToken, second.proc.Name, second.secondInParams.Select(Expr.Ident).ToList <Expr>(), second.secondOutParams.Select(Expr.Ident).ToList() ) { Proc = second.proc } }; var block = new Block(Token.NoToken, "init", cmds, new ReturnCmd(Token.NoToken)); var secondInParamsFiltered = second.secondInParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN); IEnumerable <Expr> linearityAssumes = Enumerable.Union( DisjointnessExpr(first.firstOutParams.Union(secondInParamsFiltered), frame), DisjointnessExpr(first.firstOutParams.Union(second.secondOutParams), frame)); // TODO: add further disjointness expressions? Ensures ensureCheck = new Ensures(first.proc.tok, false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation), null) { ErrorData = $"Commutativity check between {first.proc.Name} and {second.proc.Name} failed" }; List <Ensures> ensures = new List <Ensures> { ensureCheck }; List <Variable> inputs = Enumerable.Union(first.firstInParams, second.secondInParams).ToList(); List <Variable> outputs = Enumerable.Union(first.firstOutParams, second.secondOutParams).ToList(); AddChecker(checkerName, inputs, outputs, new List <Variable>(), requires, ensures, new List <Block> { block }); }