public static void AddCheckers(CivlTypeChecker ctc) { foreach (var action in ctc.AllAtomicActions.Where(a => a.HasPendingAsyncs)) { var requires = action.gate.Select(g => new Requires(false, g.Expr)).ToList(); var cmds = new List <Cmd> { CmdHelper.CallCmd( action.proc, action.impl.InParams.Select(Expr.Ident).ToList <Expr>(), action.impl.OutParams.Select(Expr.Ident).ToList()) }; var blocks = new List <Block>() { new Block(Token.NoToken, "init", cmds, CmdHelper.ReturnCmd) }; var PAs = Expr.Ident(action.impl.OutParams.Last(p => p.TypedIdent.Type.Equals(ctc.pendingAsyncMultisetType))); var paBound = VarHelper.BoundVariable("pa", ctc.pendingAsyncType); var pa = Expr.Ident(paBound); var nonnegativeExpr = new ForallExpr(Token.NoToken, new List <Variable> { paBound }, Expr.Ge(Expr.Select(PAs, pa), Expr.Literal(0))); var correctTypeExpr = new ForallExpr(Token.NoToken, new List <Variable> { paBound }, Expr.Imp( Expr.Gt(Expr.Select(PAs, pa), Expr.Literal(0)), Expr.Or(action.pendingAsyncs.Select(a => ExprHelper.FunctionCall(a.pendingAsyncCtor.membership, pa))))); var ensures = new List <Ensures> { new Ensures(false, nonnegativeExpr) { ErrorData = $"Action {action.proc.Name} might create negative pending asyncs" }, new Ensures(false, correctTypeExpr) { ErrorData = $"Action {action.proc.Name} might create undeclared pending asyncs" }, }; CivlUtil.ResolveAndTypecheck(ensures); var proc = new Procedure(Token.NoToken, $"PendingAsyncChecker_{action.proc.Name}", new List <TypeVariable>(), action.impl.InParams, action.impl.OutParams, requires, action.proc.Modifies, ensures); var impl = new Implementation(Token.NoToken, proc.Name, proc.TypeParameters, proc.InParams, proc.OutParams, new List <Variable>(), blocks) { Proc = proc }; ctc.program.AddTopLevelDeclaration(proc); ctc.program.AddTopLevelDeclaration(impl); } }
private CallCmd GetCallCmd(AtomicAction callee) { return(CmdHelper.CallCmd( callee.proc, invariantAction.impl.InParams, invariantAction.impl.OutParams.GetRange(0, callee.impl.OutParams.Count) )); }
private CallCmd GetCallCmd(AtomicAction callee) { return(CmdHelper.CallCmd( callee.proc, invariantAction.impl.InParams.Select(Expr.Ident).ToList <Expr>(), invariantAction.impl.OutParams.GetRange(0, callee.impl.OutParams.Count).Select(Expr.Ident).ToList() )); }
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); } }
public static void AddCheckers(CivlTypeChecker civlTypeChecker) { foreach (var action in civlTypeChecker.AllAtomicActions.Where(a => a.HasPendingAsyncs)) { var requires = action.gate.Select(g => new Requires(false, g.Expr)).ToList(); var PAs = Expr.Ident(action.impl.OutParams.Last(p => p.TypedIdent.Type.Equals(civlTypeChecker.pendingAsyncMultisetType))); var paBound = civlTypeChecker.BoundVariable("pa", civlTypeChecker.pendingAsyncType); var pa = Expr.Ident(paBound); var nonnegativeExpr = ExprHelper.ForallExpr(new List <Variable> { paBound }, Expr.Ge(Expr.Select(PAs, pa), Expr.Literal(0))); var correctTypeExpr = ExprHelper.ForallExpr(new List <Variable> { paBound }, Expr.Imp( Expr.Gt(Expr.Select(PAs, pa), Expr.Literal(0)), Expr.Or(action.pendingAsyncs.Select(a => ExprHelper.FunctionCall(a.pendingAsyncCtor.membership, pa))))); CivlUtil.ResolveAndTypecheck(nonnegativeExpr); CivlUtil.ResolveAndTypecheck(correctTypeExpr); var cmds = new List <Cmd> { CmdHelper.CallCmd( action.proc, action.impl.InParams.Select(Expr.Ident).ToList <Expr>(), action.impl.OutParams.Select(Expr.Ident).ToList()), CmdHelper.AssertCmd( action.proc.tok, nonnegativeExpr, $"Action {action.proc.Name} might create negative pending asyncs"), CmdHelper.AssertCmd( action.proc.tok, correctTypeExpr, $"Action {action.proc.Name} might create undeclared pending asyncs") }; var blocks = new List <Block>() { BlockHelper.Block("init", cmds) }; var proc = DeclHelper.Procedure(civlTypeChecker.AddNamePrefix($"PendingAsyncChecker_{action.proc.Name}"), action.impl.InParams, action.impl.OutParams, requires, action.proc.Modifies, new List <Ensures>()); var impl = DeclHelper.Implementation(proc, proc.InParams, proc.OutParams, new List <Variable>(), blocks); civlTypeChecker.program.AddTopLevelDeclaration(proc); civlTypeChecker.program.AddTopLevelDeclaration(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 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)); }
public Tuple <Procedure, Implementation> GenerateStepChecker(AtomicAction pendingAsync, Function pendingAsyncAdd) { this.checkName = "step"; var requires = invariantAction.gate.Select(g => new Requires(false, g.Expr)).ToList(); var ensures = new List <Ensures> { GetEnsures(GetTransitionRelation(invariantAction)) }; var locals = new List <Variable>(); if (!HasChoice) { locals.Add(choice.Decl); } List <Cmd> cmds = new List <Cmd>(); cmds.Add(GetCallCmd(invariantAction)); cmds.Add(CmdHelper.AssumeCmd(ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.membership, choice))); cmds.Add(CmdHelper.AssumeCmd(Expr.Gt(Expr.Select(PAs, choice), Expr.Literal(0)))); cmds.Add(RemoveChoice); AtomicAction abs = elim[pendingAsync]; Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); List <Expr> inputExprs = new List <Expr>(); for (int i = 0; i < abs.impl.InParams.Count; i++) { var pendingAsyncParam = ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.selectors[i], choice); map[abs.impl.InParams[i]] = pendingAsyncParam; inputExprs.Add(pendingAsyncParam); } var subst = Substituter.SubstitutionFromHashtable(map); cmds.AddRange(GetGateAsserts(abs, subst)); List <IdentifierExpr> outputVars = new List <IdentifierExpr>(); if (abs.HasPendingAsyncs) { locals.Add(newPAs.Decl); outputVars.Add(newPAs); } cmds.Add(CmdHelper.CallCmd(abs.proc, inputExprs, outputVars)); if (abs.HasPendingAsyncs) { cmds.Add(AddNewPAs(pendingAsyncAdd)); } var blocks = new List <Block> { new Block(Token.NoToken, pendingAsync.proc.Name, cmds, CmdHelper.ReturnCmd) }; return(GetCheckerTuple(requires, ensures, locals, blocks, "_" + abs.proc.Name)); }
private Implementation WrapperNoninterferenceCheckerImpl() { var linearTypeChecker = civlTypeChecker.linearTypeChecker; List <Variable> inputs = new List <Variable>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { inputs.Add(linearTypeChecker.LinearDomainInFormal(domainName)); } foreach (Variable g in civlTypeChecker.GlobalVariables) { inputs.Add(OldGlobalFormal(g)); } List <Block> blocks = new List <Block>(); TransferCmd transferCmd = CmdHelper.ReturnCmd; if (noninterferenceCheckerDecls.Count > 0) { List <Block> blockTargets = new List <Block>(); int labelCount = 0; foreach (Procedure proc in noninterferenceCheckerDecls.OfType <Procedure>()) { List <Expr> exprSeq = new List <Expr>(); foreach (Variable v in inputs) { exprSeq.Add(Expr.Ident(v)); } CallCmd callCmd = CmdHelper.CallCmd(proc, exprSeq, new List <IdentifierExpr>()); string label = $"L_{labelCount++}"; Block block = BlockHelper.Block(label, new List <Cmd> { callCmd }); blockTargets.Add(block); blocks.Add(block); } transferCmd = new GotoCmd(Token.NoToken, blockTargets); } blocks.Insert(0, new Block(Token.NoToken, "enter", new List <Cmd>(), transferCmd)); var yieldImpl = DeclHelper.Implementation(wrapperNoninterferenceCheckerProc, inputs, new List <Variable>(), new List <Variable>(), blocks); CivlUtil.AddInlineAttribute(yieldImpl); return(yieldImpl); }
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 IEnumerable <Declaration> PendingAsyncNoninterferenceCheckers() { if (CommandLineOptions.Clo.TrustNoninterference) { yield break; } HashSet <AtomicAction> pendingAsyncsToCheck = new HashSet <AtomicAction>( civlTypeChecker.procToAtomicAction.Values .Where(a => a.layerRange.Contains(layerNum) && a.HasPendingAsyncs) .SelectMany(a => a.pendingAsyncs)); foreach (var action in pendingAsyncsToCheck) { var inputs = action.impl.InParams; var outputs = action.impl.OutParams; var requires = action.gate.Select(a => new Requires(false, a.Expr)).ToList(); var ensures = new List <Ensures>(); var modifies = civlTypeChecker.GlobalVariables.Select(Expr.Ident).ToList(); var locals = globalSnapshotInstrumentation.NewLocalVars.Union(noninterferenceInstrumentation.NewLocalVars).ToList(); var cmds = new List <Cmd>(); var typeVars = new List <TypeVariable>(); cmds.AddRange(globalSnapshotInstrumentation.CreateInitCmds()); cmds.AddRange(noninterferenceInstrumentation.CreateInitCmds(action.impl)); cmds.Add(CmdHelper.CallCmd(action.proc, inputs, outputs)); cmds.AddRange(noninterferenceInstrumentation.CreateCallToYieldProc()); var blocks = new List <Block> { new Block(Token.NoToken, "init", cmds, new ReturnCmd(Token.NoToken)) }; var name = civlTypeChecker.AddNamePrefix($"PendingAsyncNoninterferenceChecker_{action.proc.Name}_{layerNum}"); var proc = new Procedure(Token.NoToken, name, typeVars, inputs, outputs, requires, modifies, ensures); var impl = new Implementation(Token.NoToken, name, typeVars, inputs, outputs, locals, blocks) { Proc = proc }; yield return(proc); yield return(impl); } }
public List <Cmd> CreateCallToYieldProc() { List <Variable> inputs = new List <Variable>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { inputs.Add(domainNameToHoleVar[domainName]); } foreach (Variable g in civlTypeChecker.GlobalVariables) { inputs.Add(oldGlobalMap[g]); } CallCmd yieldCallCmd = CmdHelper.CallCmd(yieldProc, inputs, new List <Variable>()); return(new List <Cmd> { yieldCallCmd }); }
private CallCmd ActionCallCmd(AtomicAction action, DeclWithFormals paramProvider) { return(CmdHelper.CallCmd(action.proc, paramProvider.InParams, paramProvider.OutParams)); }
private static void AddChecker(CivlTypeChecker civlTypeChecker, Action action, List<Declaration> decls) { var linearTypeChecker = civlTypeChecker.linearTypeChecker; // Note: The implementation should be used as the variables in the // gate are bound to implementation and not to the procedure. Implementation impl = action.impl; List<Variable> inputs = impl.InParams; List<Variable> outputs = impl.OutParams; List<Variable> locals = new List<Variable>(2); var paLocal1 = civlTypeChecker.LocalVariable("pa1", civlTypeChecker.pendingAsyncType); var paLocal2 = civlTypeChecker.LocalVariable("pa2", civlTypeChecker.pendingAsyncType); var pa1 = Expr.Ident(paLocal1); var pa2 = Expr.Ident(paLocal2); if (civlTypeChecker.pendingAsyncType != null) { locals.Add(paLocal1); locals.Add(paLocal2); } List<Requires> requires = action.gate.Select(a => new Requires(false, a.Expr)).ToList(); List<LinearityCheck> linearityChecks = new List<LinearityCheck>(); foreach (var domain in linearTypeChecker.linearDomains.Values) { // Linear in vars var inVars = inputs.Union(action.modifiedGlobalVars) .Where(x => linearTypeChecker.FindDomainName(x) == domain.domainName) .Where(x => InKinds.Contains(linearTypeChecker.FindLinearKind(x))) .Select(Expr.Ident) .ToList(); // Linear out vars var outVars = inputs.Union(outputs).Union(action.modifiedGlobalVars) .Where(x => linearTypeChecker.FindDomainName(x) == domain.domainName) .Where(x => OutKinds.Contains(linearTypeChecker.FindLinearKind(x))) .Select(Expr.Ident) .ToList(); // First kind // Permissions in linear output variables are a subset of permissions in linear input variables. if (outVars.Count > 0) { linearityChecks.Add(new LinearityCheck( null, OutPermsSubsetInPerms(domain, inVars, outVars), $"Potential linearity violation in outputs for domain {domain.domainName}.", "variables")); } if (action is AtomicAction atomicAction && atomicAction.HasPendingAsyncs) { var PAs = Expr.Ident(atomicAction.impl.OutParams.Last()); foreach (var pendingAsync in atomicAction.pendingAsyncs) { var pendingAsyncLinearParams = PendingAsyncLinearParams(linearTypeChecker, domain, pendingAsync, pa1); if (pendingAsyncLinearParams.Count == 0) continue; // Second kind // Permissions in linear output variables + linear inputs of a single pending async // are a subset of permissions in linear input variables. var exactlyOnePA = Expr.And( ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.membership, pa1), Expr.Eq(Expr.Select(PAs, pa1), Expr.Literal(1))); var outSubsetInExpr = OutPermsSubsetInPerms(domain, inVars, pendingAsyncLinearParams.Union(outVars)); linearityChecks.Add(new LinearityCheck( exactlyOnePA, outSubsetInExpr, $"Potential linearity violation in outputs and pending async of {pendingAsync.proc.Name} for domain {domain.domainName}.", $"single_{pendingAsync.proc.Name}")); // Third kind // If there are two identical pending asyncs, then their input permissions mut be empty. var twoIdenticalPAs = Expr.And( ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.membership, pa1), Expr.Ge(Expr.Select(PAs, pa1), Expr.Literal(2))); var emptyPerms = OutPermsSubsetInPerms(domain, Enumerable.Empty<Expr>(), pendingAsyncLinearParams); linearityChecks.Add(new LinearityCheck( twoIdenticalPAs, emptyPerms, $"Potential linearity violation in identical pending asyncs of {pendingAsync.proc.Name} for domain {domain.domainName}.", $"identical_{pendingAsync.proc.Name}")); } var pendingAsyncs = atomicAction.pendingAsyncs.ToList(); for (int i = 0; i < pendingAsyncs.Count; i++) { var pendingAsync1 = pendingAsyncs[i]; for (int j = i; j < pendingAsyncs.Count; j++) { var pendingAsync2 = pendingAsyncs[j]; var pendingAsyncLinearParams1 = PendingAsyncLinearParams(linearTypeChecker, domain, pendingAsync1, pa1); var pendingAsyncLinearParams2 = PendingAsyncLinearParams(linearTypeChecker, domain, pendingAsync2, pa2); if (pendingAsyncLinearParams1.Count == 0 || pendingAsyncLinearParams2.Count == 0) continue; // Fourth kind // Input permissions of two non-identical pending asyncs (possibly of the same action) // are a subset of permissions in linear input variables. var membership = Expr.And( Expr.Neq(pa1, pa2), Expr.And( ExprHelper.FunctionCall(pendingAsync1.pendingAsyncCtor.membership, pa1), ExprHelper.FunctionCall(pendingAsync2.pendingAsyncCtor.membership, pa2))); var existing = Expr.And( Expr.Ge(Expr.Select(PAs, pa1), Expr.Literal(1)), Expr.Ge(Expr.Select(PAs, pa2), Expr.Literal(1))); var noDuplication = OutPermsSubsetInPerms(domain, inVars, pendingAsyncLinearParams1.Union(pendingAsyncLinearParams2)); linearityChecks.Add(new LinearityCheck( Expr.And(membership, existing), noDuplication, $"Potential lnearity violation in pending asyncs of {pendingAsync1.proc.Name} and {pendingAsync2.proc.Name} for domain {domain.domainName}.", $"distinct_{pendingAsync1.proc.Name}_{pendingAsync2.proc.Name}")); } } } } if (linearityChecks.Count == 0) return; // Create checker blocks List<Block> checkerBlocks = new List<Block>(linearityChecks.Count); foreach (var lc in linearityChecks) { List<Cmd> cmds = new List<Cmd>(2); if (lc.assume != null) { cmds.Add(CmdHelper.AssumeCmd(lc.assume)); } cmds.Add(new AssertCmd(action.proc.tok, lc.assert) { ErrorData = lc.message }); var block = new Block(Token.NoToken, lc.name, cmds, CmdHelper.ReturnCmd); CivlUtil.ResolveAndTypecheck(block, ResolutionContext.State.Two); checkerBlocks.Add(block); } // Create init blocks List<Block> blocks = new List<Block>(linearityChecks.Count + 1); blocks.Add( new Block( Token.NoToken, "init", new List<Cmd> { CmdHelper.CallCmd(action.proc, inputs, outputs) }, new GotoCmd(Token.NoToken, checkerBlocks))); blocks.AddRange(checkerBlocks); // Create the whole check procedure string checkerName = civlTypeChecker.AddNamePrefix($"LinearityChecker_{action.proc.Name}"); Procedure linCheckerProc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, requires, action.proc.Modifies, new List<Ensures>()); Implementation linCheckImpl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, locals, blocks); linCheckImpl.Proc = linCheckerProc; decls.Add(linCheckImpl); decls.Add(linCheckerProc); }
public Tuple <Procedure, Implementation> GenerateStepChecker(Function pendingAsyncAdd) { this.checkName = "step"; var requires = invariantAction.gate.Select(g => new Requires(false, g.Expr)).ToList(); var ensures = new List <Ensures> { GetEnsures(GetTransitionRelation(invariantAction)) }; var locals = new List <Variable>(); if (elim.Values.Any(a => a.HasPendingAsyncs)) { locals.Add(newPAs.Decl); } List <Block> blocks = new List <Block>(); foreach (var pendingAsync in elim.Keys) { AtomicAction abs = elim[pendingAsync]; Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); List <Expr> inputExprs = new List <Expr>(); for (int i = 0; i < abs.impl.InParams.Count; i++) { var pendingAsyncParam = ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.selectors[i], choice); map[abs.impl.InParams[i]] = pendingAsyncParam; inputExprs.Add(pendingAsyncParam); } var subst = Substituter.SubstitutionFromHashtable(map); List <IdentifierExpr> outputVars = new List <IdentifierExpr>(); if (abs.HasPendingAsyncs) { outputVars.Add(newPAs); } List <Cmd> cmds = new List <Cmd>(); cmds.Add(CmdHelper.AssumeCmd(ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.membership, choice))); cmds.AddRange(GetGateAsserts(abs, subst)); cmds.Add(CmdHelper.CallCmd(abs.proc, inputExprs, outputVars)); if (abs.HasPendingAsyncs) { cmds.Add(AddNewPAs(pendingAsyncAdd)); } var block = new Block(Token.NoToken, pendingAsync.proc.Name, cmds, CmdHelper.ReturnCmd); blocks.Add(block); } { List <Cmd> cmds = new List <Cmd>(); cmds.Add(GetCallCmd(invariantAction)); if (HasChoice) { cmds.Add(new AssumeCmd(Token.NoToken, ValidChoiceExpr)); cmds.Add( new AssertCmd(Token.NoToken, ElimPendingAsyncExpr(choice)) { ErrorData = $"Failed to validate choice in IS of {inputAction.proc.Name}" } ); } else { locals.Add(choice.Decl); cmds.Add(new AssumeCmd(Token.NoToken, ElimPendingAsyncExpr(choice))); } cmds.Add(RemoveChoice); var initBlock = new Block(Token.NoToken, "init", cmds, new GotoCmd(Token.NoToken, blocks.ToList())); blocks.Insert(0, initBlock); } return(GetCheckerTuple(requires, ensures, locals, blocks)); }