private YieldingProcInstrumentation( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum, Dictionary <Absy, Absy> absyMap, Dictionary <Implementation, Implementation> implMap, HashSet <Procedure> yieldingProcs) { this.civlTypeChecker = civlTypeChecker; this.linearTypeChecker = linearTypeChecker; this.layerNum = layerNum; this.absyMap = absyMap; this.implMap = implMap; this.yieldingProcs = yieldingProcs; asyncAndParallelCallDesugarings = new Dictionary <string, Procedure>(); yieldCheckerDecls = new List <Declaration>(); List <Variable> inputs = new List <Variable>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { inputs.Add(linearTypeChecker.LinearDomainInFormal(domainName)); } foreach (Variable g in civlTypeChecker.sharedVariables) { inputs.Add(OldGlobalFormal(g)); } yieldProc = new Procedure(Token.NoToken, $"og_yield_{layerNum}", new List <TypeVariable>(), inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); CivlUtil.AddInlineAttribute(yieldProc); }
public AtomicAction(Procedure proc, Implementation impl, MoverType moverType, LayerRange layerRange) { this.proc = proc; this.impl = impl; this.moverType = moverType; this.layerRange = layerRange; CivlUtil.AddInlineAttribute(proc); CivlUtil.AddInlineAttribute(impl); // The gate of an atomic action is represented as asserts at the beginning of the procedure body. this.gate = impl.Blocks[0].cmds.TakeWhile((c, i) => c is AssertCmd).Cast <AssertCmd>().ToList(); impl.Blocks[0].cmds.RemoveRange(0, gate.Count); gateUsedGlobalVars = new HashSet <Variable>(VariableCollector.Collect(gate).Where(x => x is GlobalVariable)); actionUsedGlobalVars = new HashSet <Variable>(VariableCollector.Collect(impl).Where(x => x is GlobalVariable)); modifiedGlobalVars = new HashSet <Variable>(AssignedVariables().Where(x => x is GlobalVariable)); // We usually declare the Boogie procedure and implementation of an atomic action together. // Since Boogie only stores the supplied attributes (in particular linearity) in the procedure parameters, // we copy them into the implementation parameters here. for (int i = 0; i < proc.InParams.Count; i++) { impl.InParams[i].Attributes = proc.InParams[i].Attributes; } for (int i = 0; i < proc.OutParams.Count; i++) { impl.OutParams[i].Attributes = proc.OutParams[i].Attributes; } AtomicActionDuplicator.SetupCopy(this, ref firstGate, ref firstImpl, "first_"); AtomicActionDuplicator.SetupCopy(this, ref secondGate, ref secondImpl, "second_"); DeclareTriggerFunctions(); }
private YieldingProcInstrumentation( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, LinearPermissionInstrumentation linearPermissionInstrumentation, int layerNum, Dictionary <Absy, Absy> absyMap, Dictionary <CallCmd, Block> refinementBlocks) { this.civlTypeChecker = civlTypeChecker; this.linearTypeChecker = linearTypeChecker; this.layerNum = layerNum; this.absyMap = absyMap; this.linearPermissionInstrumentation = linearPermissionInstrumentation; this.refinementBlocks = refinementBlocks; parallelCallAggregators = new Dictionary <string, Procedure>(); noninterferenceCheckerDecls = new List <Declaration>(); 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)); } wrapperNoninterferenceCheckerProc = new Procedure(Token.NoToken, $"Wrapper_NoninterferenceChecker_{layerNum}", new List <TypeVariable>(), inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); CivlUtil.AddInlineAttribute(wrapperNoninterferenceCheckerProc); }
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 = new ReturnCmd(Token.NoToken); if (noninterferenceCheckerDecls.Count > 0) { List <Block> blockTargets = new List <Block>(); List <String> labelTargets = new List <String>(); 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 = new CallCmd(Token.NoToken, proc.Name, exprSeq, new List <IdentifierExpr>()); callCmd.Proc = proc; string label = $"L_{labelCount++}"; Block block = new Block(Token.NoToken, label, new List <Cmd> { callCmd }, new ReturnCmd(Token.NoToken)); labelTargets.Add(label); blockTargets.Add(block); blocks.Add(block); } transferCmd = new GotoCmd(Token.NoToken, labelTargets, blockTargets); } blocks.Insert(0, new Block(Token.NoToken, "enter", new List <Cmd>(), transferCmd)); var yieldImpl = new Implementation(Token.NoToken, wrapperNoninterferenceCheckerProc.Name, new List <TypeVariable>(), inputs, new List <Variable>(), new List <Variable>(), blocks); yieldImpl.Proc = wrapperNoninterferenceCheckerProc; CivlUtil.AddInlineAttribute(yieldImpl); return(yieldImpl); }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List <Declaration> decls) { Program program = linearTypeChecker.program; // Skip procedures do not completely disappear (because of output parameters). // We create dummy implementations with empty body. Dictionary <Procedure, Procedure> procToSkipProcDummy = new Dictionary <Procedure, Procedure>(); foreach (SkipProc skipProc in civlTypeChecker.procToYieldingProc.Values.OfType <SkipProc>()) { Procedure proc = (Procedure)skipProc.proc.Clone(); proc.Name = $"skip_dummy_{proc.Name}"; proc.Requires = new List <Requires>(); proc.Ensures = new List <Ensures>(); proc.Modifies = new List <IdentifierExpr>(); Block newInitBlock = new Block(Token.NoToken, "_init", new List <Cmd>(), new ReturnCmd(Token.NoToken)); List <Block> newBlocks = new List <Block> { newInitBlock }; Implementation impl = new Implementation(Token.NoToken, proc.Name, proc.TypeParameters, proc.InParams, proc.OutParams, new List <Variable>(), newBlocks); impl.Proc = proc; CivlUtil.AddInlineAttribute(proc); CivlUtil.AddInlineAttribute(impl); decls.Add(proc); decls.Add(impl); procToSkipProcDummy.Add(skipProc.proc, proc); } // Generate the refinement checks for every layer foreach (int layerNum in civlTypeChecker.allRefinementLayers) { if (CommandLineOptions.Clo.TrustLayersDownto <= layerNum || layerNum <= CommandLineOptions.Clo.TrustLayersUpto) { continue; } YieldingProcDuplicator duplicator = new YieldingProcDuplicator(civlTypeChecker, linearTypeChecker, layerNum, procToSkipProcDummy); // We can not simply call VisitProgram, because it does some resolving of calls // that is not necessary here (and actually fails). foreach (Procedure proc in program.Procedures) { duplicator.VisitProcedure(proc); } foreach (Implementation impl in program.Implementations) { duplicator.VisitImplementation(impl); } decls.AddRange(duplicator.Collect()); } }
private YieldingProcInstrumentation( CivlTypeChecker civlTypeChecker, LinearPermissionInstrumentation linearPermissionInstrumentation, int layerNum, AbsyMap absyMap, Dictionary <CallCmd, Block> refinementBlocks) { this.civlTypeChecker = civlTypeChecker; this.layerNum = layerNum; this.absyMap = absyMap; this.linearPermissionInstrumentation = linearPermissionInstrumentation; this.refinementBlocks = refinementBlocks; parallelCallAggregators = new Dictionary <string, Procedure>(); noninterferenceCheckerDecls = new List <Declaration>(); 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)); } wrapperNoninterferenceCheckerProc = new Procedure(Token.NoToken, civlTypeChecker.AddNamePrefix($"Wrapper_NoninterferenceChecker_{layerNum}"), new List <TypeVariable>(), inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); CivlUtil.AddInlineAttribute(wrapperNoninterferenceCheckerProc); // initialize globalSnapshotInstrumentation globalSnapshotInstrumentation = new GlobalSnapshotInstrumentation(civlTypeChecker); // initialize noninterferenceInstrumentation if (CommandLineOptions.Clo.TrustNoninterference) { noninterferenceInstrumentation = new NoneNoninterferenceInstrumentation(); } else { noninterferenceInstrumentation = new SomeNoninterferenceInstrumentation( civlTypeChecker, linearTypeChecker, linearPermissionInstrumentation, globalSnapshotInstrumentation.OldGlobalMap, wrapperNoninterferenceCheckerProc); } }
public static List <Declaration> CreateNoninterferenceCheckers( CivlTypeChecker civlTypeChecker, int layerNum, AbsyMap absyMap, DeclWithFormals decl, List <Variable> declLocalVariables) { var linearTypeChecker = civlTypeChecker.linearTypeChecker; Dictionary <string, Variable> domainNameToHoleVar = new Dictionary <string, Variable>(); Dictionary <Variable, Variable> localVarMap = new Dictionary <Variable, Variable>(); Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); List <Variable> locals = new List <Variable>(); List <Variable> inputs = new List <Variable>(); foreach (var domainName in linearTypeChecker.linearDomains.Keys) { var inParam = linearTypeChecker.LinearDomainInFormal(domainName); inputs.Add(inParam); domainNameToHoleVar[domainName] = inParam; } foreach (Variable local in declLocalVariables.Union(decl.InParams).Union(decl.OutParams)) { var copy = CopyLocal(local); locals.Add(copy); localVarMap[local] = copy; map[local] = Expr.Ident(copy); } Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>(); Dictionary <Variable, Expr> assumeMap = new Dictionary <Variable, Expr>(map); foreach (Variable g in civlTypeChecker.GlobalVariables) { var copy = OldGlobalLocal(civlTypeChecker, g); locals.Add(copy); oldLocalMap[g] = Expr.Ident(copy); Formal f = SnapshotGlobalFormal(civlTypeChecker, g); inputs.Add(f); assumeMap[g] = Expr.Ident(f); } var linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker, layerNum, absyMap, domainNameToHoleVar, localVarMap); List <YieldInfo> yieldInfos = null; string noninterferenceCheckerName = null; if (decl is Implementation impl) { noninterferenceCheckerName = $"impl_{absyMap.Original(impl).Name}_{layerNum}"; yieldInfos = CollectYields(civlTypeChecker, absyMap, layerNum, impl).Select(kv => new YieldInfo(linearPermissionInstrumentation.DisjointnessAssumeCmds(kv.Key, false), kv.Value)).ToList(); } else if (decl is Procedure proc) { yieldInfos = new List <YieldInfo>(); if (civlTypeChecker.procToYieldInvariant.ContainsKey(proc)) { noninterferenceCheckerName = $"yield_{proc.Name}"; if (proc.Requires.Count > 0) { var disjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true); var yieldPredicates = proc.Requires.Select(requires => requires.Free ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition) : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList(); yieldInfos.Add(new YieldInfo(disjointnessCmds, yieldPredicates)); } } else { noninterferenceCheckerName = $"proc_{absyMap.Original(proc).Name}_{layerNum}"; if (proc.Requires.Count > 0) { var entryDisjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true); var entryYieldPredicates = proc.Requires.Select(requires => requires.Free ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition) : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList(); yieldInfos.Add(new YieldInfo(entryDisjointnessCmds, entryYieldPredicates)); } if (proc.Ensures.Count > 0) { var exitDisjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, false); var exitYieldPredicates = proc.Ensures.Select(ensures => ensures.Free ? (PredicateCmd) new AssumeCmd(ensures.tok, ensures.Condition) : (PredicateCmd) new AssertCmd(ensures.tok, ensures.Condition)).ToList(); yieldInfos.Add(new YieldInfo(exitDisjointnessCmds, exitYieldPredicates)); } } } else { Debug.Assert(false); } var filteredYieldInfos = yieldInfos.Where(info => info.invariantCmds.Any(predCmd => new GlobalAccessChecker().AccessesGlobal(predCmd.Expr))); if (filteredYieldInfos.Count() == 0) { return(new List <Declaration>()); } Substitution assumeSubst = Substituter.SubstitutionFromDictionary(assumeMap); Substitution oldSubst = Substituter.SubstitutionFromDictionary(oldLocalMap); Substitution subst = Substituter.SubstitutionFromDictionary(map); List <Block> noninterferenceCheckerBlocks = new List <Block>(); List <Block> labelTargets = new List <Block>(); Block noninterferenceCheckerBlock = BlockHelper.Block("exit", new List <Cmd>()); labelTargets.Add(noninterferenceCheckerBlock); noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock); int yieldCount = 0; foreach (var kv in filteredYieldInfos) { var newCmds = new List <Cmd>(kv.disjointnessCmds); foreach (var predCmd in kv.invariantCmds) { var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr); newCmds.Add(new AssumeCmd(predCmd.tok, newExpr)); } foreach (var predCmd in kv.invariantCmds) { if (predCmd is AssertCmd) { var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr); AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes); assertCmd.ErrorData = "Non-interference check failed"; newCmds.Add(assertCmd); } } newCmds.Add(CmdHelper.AssumeCmd(Expr.False)); noninterferenceCheckerBlock = BlockHelper.Block("L" + yieldCount++, newCmds); labelTargets.Add(noninterferenceCheckerBlock); noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock); } noninterferenceCheckerBlocks.Insert(0, BlockHelper.Block("enter", new List <Cmd>(), labelTargets)); // Create the yield checker procedure noninterferenceCheckerName = civlTypeChecker.AddNamePrefix($"NoninterferenceChecker_{noninterferenceCheckerName}"); var noninterferenceCheckerProc = DeclHelper.Procedure(noninterferenceCheckerName, inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); CivlUtil.AddInlineAttribute(noninterferenceCheckerProc); // Create the yield checker implementation var noninterferenceCheckerImpl = DeclHelper.Implementation(noninterferenceCheckerProc, inputs, new List <Variable>(), locals, noninterferenceCheckerBlocks); CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl); return(new List <Declaration> { noninterferenceCheckerProc, noninterferenceCheckerImpl }); }
public List <Declaration> CreateYieldCheckerProcImpl( Implementation impl, IEnumerable <List <PredicateCmd> > yields) { Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); List <Variable> locals = new List <Variable>(); List <Variable> inputs = new List <Variable>(); foreach (Variable local in impl.LocVars.Union(impl.InParams).Union(impl.OutParams)) { var copy = CopyLocal(local); locals.Add(copy); map[local] = Expr.Ident(copy); } foreach (var domainName in linearTypeChecker.linearDomains.Keys) { var inParam = linearTypeChecker.LinearDomainInFormal(domainName); inputs.Add(inParam); map[linearTypeChecker.domainNameToHoleVar[domainName]] = Expr.Ident(inParam); } Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>(); Dictionary <Variable, Expr> assumeMap = new Dictionary <Variable, Expr>(map); foreach (Variable g in civlTypeChecker.sharedVariables) { var copy = OldLocalLocal(g); locals.Add(copy); oldLocalMap[g] = Expr.Ident(copy); Formal f = OldGlobalFormal(g); inputs.Add(f); assumeMap[g] = Expr.Ident(f); } Substitution assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap); Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldLocalMap); Substitution subst = Substituter.SubstitutionFromHashtable(map); List <Block> yieldCheckerBlocks = new List <Block>(); List <String> labels = new List <String>(); List <Block> labelTargets = new List <Block>(); Block yieldCheckerBlock = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken)); labels.Add(yieldCheckerBlock.Label); labelTargets.Add(yieldCheckerBlock); yieldCheckerBlocks.Add(yieldCheckerBlock); int yieldCount = 0; foreach (var cs in yields) { List <Cmd> newCmds = new List <Cmd>(); foreach (var predCmd in cs) { var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr); newCmds.Add(new AssumeCmd(Token.NoToken, newExpr)); } foreach (var predCmd in cs) { if (predCmd is AssertCmd) { var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr); AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes); assertCmd.ErrorData = "Non-interference check failed"; newCmds.Add(assertCmd); } /* * Disjointness assumes injected by LinearTypeChecker are dropped now because the * previous loop has already substituted the old global state in these assumes. * It would be unsound to have these assumes on the current global state. */ } newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False)); yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken)); labels.Add(yieldCheckerBlock.Label); labelTargets.Add(yieldCheckerBlock); yieldCheckerBlocks.Add(yieldCheckerBlock); } yieldCheckerBlocks.Insert(0, new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets))); // Create the yield checker procedure var yieldCheckerName = $"Impl_YieldChecker_{impl.Name}"; var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); CivlUtil.AddInlineAttribute(yieldCheckerProc); // Create the yield checker implementation var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List <Variable>(), locals, yieldCheckerBlocks); yieldCheckerImpl.Proc = yieldCheckerProc; CivlUtil.AddInlineAttribute(yieldCheckerImpl); return(new List <Declaration> { yieldCheckerProc, yieldCheckerImpl }); }
public static List <Declaration> CreateNoninterferenceCheckers( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum, Dictionary <Absy, Absy> absyMap, Implementation impl, Dictionary <YieldCmd, List <PredicateCmd> > yields) { Dictionary <string, Variable> domainNameToHoleVar = new Dictionary <string, Variable>(); Dictionary <Variable, Variable> localVarMap = new Dictionary <Variable, Variable>(); Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); List <Variable> locals = new List <Variable>(); List <Variable> inputs = new List <Variable>(); foreach (var domainName in linearTypeChecker.linearDomains.Keys) { var inParam = linearTypeChecker.LinearDomainInFormal(domainName); inputs.Add(inParam); domainNameToHoleVar[domainName] = inParam; } foreach (Variable local in impl.LocVars.Union(impl.InParams).Union(impl.OutParams)) { var copy = CopyLocal(local); locals.Add(copy); localVarMap[local] = copy; map[local] = Expr.Ident(copy); } Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>(); Dictionary <Variable, Expr> assumeMap = new Dictionary <Variable, Expr>(map); foreach (Variable g in civlTypeChecker.GlobalVariables) { var copy = OldLocalLocal(g); locals.Add(copy); oldLocalMap[g] = Expr.Ident(copy); Formal f = OldGlobalFormal(g); inputs.Add(f); assumeMap[g] = Expr.Ident(f); } var linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap, domainNameToHoleVar, localVarMap); Substitution assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap); Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldLocalMap); Substitution subst = Substituter.SubstitutionFromHashtable(map); List <Block> noninterferenceCheckerBlocks = new List <Block>(); List <String> labels = new List <String>(); List <Block> labelTargets = new List <Block>(); Block noninterferenceCheckerBlock = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken)); labels.Add(noninterferenceCheckerBlock.Label); labelTargets.Add(noninterferenceCheckerBlock); noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock); int yieldCount = 0; foreach (var kv in yields) { var yieldCmd = kv.Key; var yieldPredicates = kv.Value; List <Cmd> newCmds = linearPermissionInstrumentation.DisjointnessAssumeCmds(yieldCmd, false); foreach (var predCmd in yieldPredicates) { var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr); newCmds.Add(new AssumeCmd(Token.NoToken, newExpr)); } foreach (var predCmd in yieldPredicates) { if (predCmd is AssertCmd) { var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr); AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes); assertCmd.ErrorData = "Non-interference check failed"; newCmds.Add(assertCmd); } } newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False)); noninterferenceCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken)); labels.Add(noninterferenceCheckerBlock.Label); labelTargets.Add(noninterferenceCheckerBlock); noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock); } noninterferenceCheckerBlocks.Insert(0, new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets))); // Create the yield checker procedure var noninterferenceCheckerName = $"NoninterferenceChecker_{impl.Name}"; var noninterferenceCheckerProc = new Procedure(Token.NoToken, noninterferenceCheckerName, impl.TypeParameters, inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); CivlUtil.AddInlineAttribute(noninterferenceCheckerProc); // Create the yield checker implementation var noninterferenceCheckerImpl = new Implementation(Token.NoToken, noninterferenceCheckerName, impl.TypeParameters, inputs, new List <Variable>(), locals, noninterferenceCheckerBlocks); noninterferenceCheckerImpl.Proc = noninterferenceCheckerProc; CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl); return(new List <Declaration> { noninterferenceCheckerProc, noninterferenceCheckerImpl }); }
public static List <Declaration> CreateNoninterferenceCheckers( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum, Dictionary <Absy, Absy> absyMap, DeclWithFormals decl, List <Variable> declLocalVariables) { Dictionary <string, Variable> domainNameToHoleVar = new Dictionary <string, Variable>(); Dictionary <Variable, Variable> localVarMap = new Dictionary <Variable, Variable>(); Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); List <Variable> locals = new List <Variable>(); List <Variable> inputs = new List <Variable>(); foreach (var domainName in linearTypeChecker.linearDomains.Keys) { var inParam = linearTypeChecker.LinearDomainInFormal(domainName); inputs.Add(inParam); domainNameToHoleVar[domainName] = inParam; } foreach (Variable local in declLocalVariables.Union(decl.InParams).Union(decl.OutParams)) { var copy = CopyLocal(local); locals.Add(copy); localVarMap[local] = copy; map[local] = Expr.Ident(copy); } Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>(); Dictionary <Variable, Expr> assumeMap = new Dictionary <Variable, Expr>(map); foreach (Variable g in civlTypeChecker.GlobalVariables) { var copy = OldLocalLocal(g); locals.Add(copy); oldLocalMap[g] = Expr.Ident(copy); Formal f = OldGlobalFormal(g); inputs.Add(f); assumeMap[g] = Expr.Ident(f); } var linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap, domainNameToHoleVar, localVarMap); List <Tuple <List <Cmd>, List <PredicateCmd> > > yieldInfo = null; if (decl is Implementation impl) { yieldInfo = CollectYields(civlTypeChecker, absyMap, layerNum, impl).Select(kv => new Tuple <List <Cmd>, List <PredicateCmd> >(linearPermissionInstrumentation.DisjointnessAssumeCmds(kv.Key, false), kv.Value)).ToList(); } else if (decl is Procedure proc) { yieldInfo = new List <Tuple <List <Cmd>, List <PredicateCmd> > >(); if (civlTypeChecker.procToYieldInvariant.ContainsKey(proc)) { if (proc.Requires.Count > 0) { var disjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true); var yieldPredicates = proc.Requires.Select(requires => requires.Free ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition) : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList(); yieldInfo.Add(new Tuple <List <Cmd>, List <PredicateCmd> >(disjointnessCmds, yieldPredicates)); } } else { if (proc.Requires.Count > 0) { var entryDisjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true); var entryYieldPredicates = proc.Requires.Select(requires => requires.Free ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition) : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList(); yieldInfo.Add( new Tuple <List <Cmd>, List <PredicateCmd> >(entryDisjointnessCmds, entryYieldPredicates)); } if (proc.Ensures.Count > 0) { var exitDisjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, false); var exitYieldPredicates = proc.Ensures.Select(ensures => ensures.Free ? (PredicateCmd) new AssumeCmd(ensures.tok, ensures.Condition) : (PredicateCmd) new AssertCmd(ensures.tok, ensures.Condition)).ToList(); yieldInfo.Add( new Tuple <List <Cmd>, List <PredicateCmd> >(exitDisjointnessCmds, exitYieldPredicates)); } } } else { Debug.Assert(false); } Substitution assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap); Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldLocalMap); Substitution subst = Substituter.SubstitutionFromHashtable(map); List <Block> noninterferenceCheckerBlocks = new List <Block>(); List <String> labels = new List <String>(); List <Block> labelTargets = new List <Block>(); Block noninterferenceCheckerBlock = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken)); labels.Add(noninterferenceCheckerBlock.Label); labelTargets.Add(noninterferenceCheckerBlock); noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock); int yieldCount = 0; foreach (var kv in yieldInfo) { var disjointnessCmds = kv.Item1; var yieldPredicates = kv.Item2; var newCmds = new List <Cmd>(disjointnessCmds); foreach (var predCmd in yieldPredicates) { var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr); newCmds.Add(new AssumeCmd(Token.NoToken, newExpr)); } foreach (var predCmd in yieldPredicates) { if (predCmd is AssertCmd) { var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr); AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes); assertCmd.ErrorData = "Non-interference check failed"; newCmds.Add(assertCmd); } } newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False)); noninterferenceCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken)); labels.Add(noninterferenceCheckerBlock.Label); labelTargets.Add(noninterferenceCheckerBlock); noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock); } noninterferenceCheckerBlocks.Insert(0, new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets))); // Create the yield checker procedure var noninterferenceCheckerName = decl is Procedure ? $"NoninterferenceChecker_proc_{decl.Name}" : $"NoninterferenceChecker_impl_{decl.Name}"; var noninterferenceCheckerProc = new Procedure(Token.NoToken, noninterferenceCheckerName, decl.TypeParameters, inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); CivlUtil.AddInlineAttribute(noninterferenceCheckerProc); // Create the yield checker implementation var noninterferenceCheckerImpl = new Implementation(Token.NoToken, noninterferenceCheckerName, decl.TypeParameters, inputs, new List <Variable>(), locals, noninterferenceCheckerBlocks); noninterferenceCheckerImpl.Proc = noninterferenceCheckerProc; CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl); return(new List <Declaration> { noninterferenceCheckerProc, noninterferenceCheckerImpl }); }