internal PathTranslation(TransitionRelationComputation transitionRelationComputer, List <Cmd> cmds) { this.cmds = cmds; this.transitionRelationComputer = transitionRelationComputer; this.frame = transitionRelationComputer.frame; this.first = transitionRelationComputer.first; this.second = transitionRelationComputer.second; allInParams = new HashSet <Variable>(first.InParams); allOutParams = new HashSet <Variable>(first.OutParams); allLocVars = new HashSet <Variable>(first.LocVars); frameIntermediateCopy = new Dictionary <Variable, Variable>(); if (IsJoint()) { allInParams.UnionWith(second.InParams); allOutParams.UnionWith(second.OutParams); allLocVars.UnionWith(second.LocVars); } SetupVarCopies(); IntroduceIntermediateVars(); EliminateIntermediateVariables(); if (IsJoint()) { EliminateWithIntermediateState(); } ComputeTransitionRelationExpr(); }
public static void AddChecks(CivlTypeChecker ctc) { foreach (var x in ctc.inductiveSequentializations) { var t = x.GenerateBaseCaseChecker(); ctc.program.AddTopLevelDeclaration(t.Item1); ctc.program.AddTopLevelDeclaration(t.Item2); t = x.GenerateConclusionChecker(); ctc.program.AddTopLevelDeclaration(t.Item1); ctc.program.AddTopLevelDeclaration(t.Item2); t = x.GenerateStepChecker(ctc.pendingAsyncAdd); ctc.program.AddTopLevelDeclaration(t.Item1); ctc.program.AddTopLevelDeclaration(t.Item2); } var absChecks = ctc.inductiveSequentializations.SelectMany(x => x.elim).Where(kv => kv.Key != kv.Value).Distinct(); foreach (var absCheck in absChecks) { var action = absCheck.Key; var abs = absCheck.Value; var requires = abs.gate.Select(g => new Requires(false, g.Expr)).ToList(); // TODO: check frame computation var frame = new HashSet <Variable>(action.modifiedGlobalVars.Union(action.gateUsedGlobalVars).Union(abs.modifiedGlobalVars).Union(abs.gateUsedGlobalVars)); var tr = TransitionRelationComputation.Refinement(abs, frame); var ensures = new List <Ensures> { new Ensures(false, tr) { ErrorData = $"Abstraction {abs.proc.Name} does not summarize {action.proc.Name}" } }; var subst = InductiveSequentialization.GetSubstitution(action, abs); List <Cmd> cmds = InductiveSequentialization.GetGateAsserts(action, subst, $"Abstraction {abs.proc.Name} fails gate of {action.proc.Name}").ToList <Cmd>(); cmds.Add( CmdHelper.CallCmd( action.proc, abs.impl.InParams.Select(Expr.Ident).ToList <Expr>(), abs.impl.OutParams.Select(Expr.Ident).ToList() )); var blocks = new List <Block> { new Block(Token.NoToken, "init", cmds, CmdHelper.ReturnCmd) }; var proc = new Procedure(Token.NoToken, $"AbstractionCheck_{action.proc.Name}_{abs.proc.Name}", new List <TypeVariable>(), abs.impl.InParams, abs.impl.OutParams, requires, abs.modifiedGlobalVars.Select(Expr.Ident).ToList(), ensures); var impl = new Implementation(Token.NoToken, proc.Name, new List <TypeVariable>(), proc.InParams, proc.OutParams, new List <Variable>(), blocks) { Proc = proc }; ctc.program.AddTopLevelDeclaration(proc); ctc.program.AddTopLevelDeclaration(impl); } }
private Expr GetTransitionRelation(AtomicAction action) { var tr = TransitionRelationComputation.Refinement(civlTypeChecker, action, frame); if (action == invariantAction && HasChoice) { return(new ChoiceEraser(invariantAction.impl.OutParams.Last()).VisitExpr(tr)); } return(tr); }
public PathTranslation(TransitionRelationComputation trc) { this.trc = trc; SetupVarCopies(); IntroduceIntermediateVars(); SetDefinedVariables(); EliminateIntermediateVariables(); ComputeTransitionRelationExpr(); }
private Expr GetTransitionRelation(AtomicAction atomicAction) { if (!transitionRelationCache.ContainsKey(atomicAction)) { transitionRelationCache[atomicAction] = TransitionRelationComputation.Refinement(civlTypeChecker, atomicAction, new HashSet <Variable>(this.oldGlobalMap.Keys)); } return(transitionRelationCache[atomicAction]); }
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 Tuple <Procedure, Implementation> GenerateAbstractionChecker(CivlTypeChecker civlTypeChecker, AtomicAction action, AtomicAction abs) { var requires = abs.gate.Select(g => new Requires(false, g.Expr)).ToList(); // TODO: check frame computation var frame = new HashSet <Variable>( action.modifiedGlobalVars .Union(action.gateUsedGlobalVars) .Union(abs.modifiedGlobalVars) .Union(abs.gateUsedGlobalVars)); var tr = TransitionRelationComputation.Refinement(civlTypeChecker, abs, frame); var ensures = new List <Ensures> { new Ensures(false, tr) { ErrorData = $"Abstraction {abs.proc.Name} does not summarize {action.proc.Name}" } }; var subst = InductiveSequentialization.GetSubstitution(action, abs); List <Cmd> cmds = InductiveSequentialization.GetGateAsserts(action, subst, $"Abstraction {abs.proc.Name} fails gate of {action.proc.Name}").ToList <Cmd>(); cmds.Add( CmdHelper.CallCmd( action.proc, abs.impl.InParams.Select(Expr.Ident).ToList <Expr>(), abs.impl.OutParams.Select(Expr.Ident).ToList() )); var blocks = new List <Block> { new Block(Token.NoToken, "init", cmds, CmdHelper.ReturnCmd) }; var proc = new Procedure( Token.NoToken, civlTypeChecker.AddNamePrefix($"AbstractionCheck_{action.proc.Name}_{abs.proc.Name}"), new List <TypeVariable>(), abs.impl.InParams, abs.impl.OutParams, requires, action.proc.Modifies, ensures); var impl = new Implementation( Token.NoToken, proc.Name, new List <TypeVariable>(), proc.InParams, proc.OutParams, new List <Variable>(), blocks) { Proc = proc }; return(Tuple.Create(proc, impl)); }
private static Tuple <Procedure, Implementation> GenerateAbstractionChecker(CivlTypeChecker civlTypeChecker, AtomicAction action, AtomicAction abs) { var requires = abs.gate.Select(g => new Requires(false, g.Expr)).ToList(); // TODO: check frame computation var frame = new HashSet <Variable>( action.modifiedGlobalVars .Union(action.gateUsedGlobalVars) .Union(abs.modifiedGlobalVars) .Union(abs.gateUsedGlobalVars)); var subst = InductiveSequentialization.GetSubstitution(action, abs); List <Cmd> cmds = InductiveSequentialization.GetGateAsserts(action, subst, $"Abstraction {abs.proc.Name} fails gate of {action.proc.Name}").ToList <Cmd>(); cmds.Add( CmdHelper.CallCmd( action.proc, abs.impl.InParams, abs.impl.OutParams )); cmds.Add( CmdHelper.AssertCmd( abs.proc.tok, TransitionRelationComputation.Refinement(civlTypeChecker, abs, frame), $"Abstraction {abs.proc.Name} does not summarize {action.proc.Name}" )); var blocks = new List <Block> { BlockHelper.Block("init", cmds) }; var proc = DeclHelper.Procedure( civlTypeChecker.AddNamePrefix($"AbstractionCheck_{action.proc.Name}_{abs.proc.Name}"), abs.impl.InParams, abs.impl.OutParams, requires, action.proc.Modifies, new List <Ensures>()); var impl = DeclHelper.Implementation( proc, proc.InParams, proc.OutParams, new List <Variable>(), blocks); return(Tuple.Create(proc, impl)); }
private static Expr ComputeTransitionRelation( Implementation first, Implementation second, IEnumerable <Variable> frame, Dictionary <Variable, Function> triggers, IEnumerable <CommutativityWitness> witnesses, bool ignorePostState, string messagePrefix) { var trc = new TransitionRelationComputation(first, second, frame, witnesses, triggers, ignorePostState, messagePrefix); trc.EnumeratePaths(); var transitionRelation = Expr.Or(trc.pathTranslations); transitionRelation.Resolve(new ResolutionContext(null) { StateMode = ResolutionContext.State.Two }); transitionRelation.Typecheck(new TypecheckingContext(null)); return(transitionRelation); }
private void CreateNonBlockingChecker(AtomicAction 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 }); }
private static Expr ComputeTransitionRelation( AtomicActionCopyAdapter first, AtomicActionCopyAdapter second, IEnumerable <Variable> frame, List <WitnessFunction> witnesses, bool ignorePostState, string messagePrefix) { var trc = new TransitionRelationComputation(first, second, frame, witnesses, ignorePostState, messagePrefix); trc.EnumeratePaths(); var transitionRelation = Expr.Or(trc.pathTranslations); ResolutionContext rc = new ResolutionContext(null) { StateMode = ResolutionContext.State.Two }; transitionRelation.Resolve(rc); transitionRelation.Typecheck(new TypecheckingContext(null)); return(transitionRelation); }
private void CreateCooperationChecker(Action action) { if (!action.HasAssumeCmd) { return; } string checkerName = $"CooperationChecker_{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 => civlTypeChecker.linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame) }; foreach (AssertCmd assertCmd in action.gate) { requires.Add(new Requires(false, assertCmd.Expr)); } AssertCmd cooperationCheck = CmdHelper.AssertCmd( action.proc.tok, TransitionRelationComputation.Cooperation(civlTypeChecker, action, frame), $"Cooperation check for {action.proc.Name} failed"); AddChecker(checkerName, new List <Variable>(impl.InParams), new List <Variable>(), new List <Variable>(), requires, new List <Cmd> { cooperationCheck }); }
private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second) { if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0) { return; } if (first.CommutesWith(second)) { return; } if (!commutativityCheckerCache.Add(new Tuple <AtomicActionInfo, AtomicActionInfo>(first, second))) { return; } List <Variable> inputs = Enumerable.Union(first.thatInParams, second.thisInParams).ToList(); List <Variable> outputs = Enumerable.Union(first.thatOutParams, second.thisOutParams).ToList(); List <Variable> locals = Enumerable.Union(first.thatAction.LocVars, second.thisAction.LocVars).ToList(); List <Block> firstBlocks = CloneBlocks(first.thatAction.Blocks); List <Block> secondBlocks = CloneBlocks(second.thisAction.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(Token.NoToken, ls, bs); } List <Block> blocks = Enumerable.Union(firstBlocks, secondBlocks).ToList(); 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(program, first.thatInParams.Union(second.thisInParams), frame)); foreach (AssertCmd assertCmd in Enumerable.Union(first.thatGate, second.thisGate)) { requires.Add(new Requires(false, assertCmd.Expr)); } var transitionRelationComputation = new TransitionRelationComputation(program, 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 thisInParamsFiltered = second.thisInParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN); IEnumerable <Expr> linearityAssumes = Enumerable.Union( DisjointnessExpr(program, first.thatOutParams.Union(thisInParamsFiltered), frame), DisjointnessExpr(program, first.thatOutParams.Union(second.thisOutParams), frame)); // TODO: add further disjointness expressions? Ensures ensureCheck = new Ensures(false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation)); 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); List <IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList(); Procedure proc = new Procedure(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, outputs, requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, outputs, locals, blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private void CreateCommutativityChecker(AtomicAction first, AtomicAction second) { if (first == second && first.firstImpl.InParams.Count == 0 && first.firstImpl.OutParams.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.firstImpl.InParams.Union(second.secondImpl.InParams) .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 witnesses = civlTypeChecker.commutativityHints.GetWitnesses(first, second); var transitionRelation = TransitionRelationComputation.Commutativity(second, first, frame, witnesses); List <Cmd> cmds = new List <Cmd> { new CallCmd(Token.NoToken, first.proc.Name, first.firstImpl.InParams.Select(Expr.Ident).ToList <Expr>(), first.firstImpl.OutParams.Select(Expr.Ident).ToList() ) { Proc = first.proc }, new CallCmd(Token.NoToken, second.proc.Name, second.secondImpl.InParams.Select(Expr.Ident).ToList <Expr>(), second.secondImpl.OutParams.Select(Expr.Ident).ToList() ) { Proc = second.proc } }; foreach (var lemma in civlTypeChecker.commutativityHints.GetLemmas(first, second)) { cmds.Add(CmdHelper.AssumeCmd(ExprHelper.FunctionCall(lemma.function, lemma.args.ToArray()))); } var block = new Block(Token.NoToken, "init", cmds, new ReturnCmd(Token.NoToken)); var secondInParamsFiltered = second.secondImpl.InParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN); IEnumerable <Expr> linearityAssumes = Enumerable.Union( linearTypeChecker.DisjointnessExprForEachDomain(first.firstImpl.OutParams.Union(secondInParamsFiltered) .Union(frame)), linearTypeChecker.DisjointnessExprForEachDomain(first.firstImpl.OutParams.Union(second.secondImpl.OutParams) .Union(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.firstImpl.InParams, second.secondImpl.InParams).ToList(); List <Variable> outputs = Enumerable.Union(first.firstImpl.OutParams, second.secondImpl.OutParams).ToList(); AddChecker(checkerName, inputs, outputs, new List <Variable>(), requires, ensures, new List <Block> { block }); }
private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second) { if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0) return; if (first.CommutesWith(second)) return; if (!commutativityCheckerCache.Add(new Tuple<AtomicActionInfo, AtomicActionInfo>(first, second))) return; List<Variable> inputs = Enumerable.Union(first.thatInParams, second.thisInParams).ToList(); List<Variable> outputs = Enumerable.Union(first.thatOutParams, second.thisOutParams).ToList(); List<Variable> locals = Enumerable.Union(first.thatAction.LocVars, second.thisAction.LocVars).ToList(); List<Block> firstBlocks = CloneBlocks(first.thatAction.Blocks); List<Block> secondBlocks = CloneBlocks(second.thisAction.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(Token.NoToken, ls, bs); } List<Block> blocks = Enumerable.Union(firstBlocks, secondBlocks).ToList(); 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(program, first.thatInParams.Union(second.thisInParams), frame)); foreach (AssertCmd assertCmd in Enumerable.Union(first.thatGate, second.thisGate)) requires.Add(new Requires(false, assertCmd.Expr)); var transitionRelationComputation = new TransitionRelationComputation(program, 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); } IEnumerable<Expr> linearityAssumes = DisjointnessExpr(program, first.thatOutParams.Union(second.thisInParams), frame).Union(DisjointnessExpr(program, first.thatOutParams.Union(second.thisOutParams), frame)); Ensures ensureCheck = new Ensures(false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation)); 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); List<IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList(); Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, locals, blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
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); }