public static List <Declaration> TransformImplementations( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum, Dictionary <Absy, Absy> absyMap, HashSet <Procedure> yieldingProcs, Dictionary <CallCmd, Block> refinementBlocks) { var linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap); var yieldingProcInstrumentation = new YieldingProcInstrumentation( civlTypeChecker, linearTypeChecker, linearPermissionInstrumentation, layerNum, absyMap, refinementBlocks); yieldingProcInstrumentation.AddNoninterferenceCheckers(); var implToPreconditions = yieldingProcInstrumentation.CreatePreconditions(linearPermissionInstrumentation); yieldingProcInstrumentation .InlineYieldRequiresAndEnsures(); // inline after creating the preconditions but before transforming the implementations yieldingProcInstrumentation.TransformImpls(yieldingProcs, implToPreconditions); List <Declaration> decls = new List <Declaration>(yieldingProcInstrumentation.noninterferenceCheckerDecls); foreach (Procedure proc in yieldingProcInstrumentation.parallelCallAggregators.Values) { decls.Add(proc); } decls.Add(yieldingProcInstrumentation.wrapperNoninterferenceCheckerProc); decls.Add(yieldingProcInstrumentation.WrapperNoninterferenceCheckerImpl()); return(decls); }
public static void Transform(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker) { Program program = linearTypeChecker.program; // Store the original declarations of yielding procedures, which will be removed after desugaring below. var origProc = program.TopLevelDeclarations.OfType <Procedure>().Where(p => civlTypeChecker.procToYieldingProc.ContainsKey(p)); var origImpl = program.TopLevelDeclarations.OfType <Implementation>().Where(i => civlTypeChecker.procToYieldingProc.ContainsKey(i.Proc)); List <Declaration> originalDecls = Enumerable.Union <Declaration>(origProc, origImpl).ToList(); // Commutativity checks List <Declaration> decls = new List <Declaration>(); if (!CommandLineOptions.Clo.TrustAtomicityTypes) { MoverCheck.AddCheckers(linearTypeChecker, civlTypeChecker, decls); } // Desugaring of yielding procedures CivlRefinement.AddCheckers(linearTypeChecker, civlTypeChecker, decls); // Trigger functions for existential vairables in transition relations decls.AddRange(civlTypeChecker.procToAtomicAction.Values.SelectMany(a => a.layerToActionCopy.Values.SelectMany(ac => ac.triggerFuns.Values))); // Remove original declarations and add new checkers generated above program.RemoveTopLevelDeclarations(x => originalDecls.Contains(x)); program.AddTopLevelDeclarations(decls); foreach (AtomicAction atomicAction in civlTypeChecker.procToAtomicAction.Values) { program.RemoveTopLevelDeclaration(atomicAction.proc); program.RemoveTopLevelDeclaration(atomicAction.impl); } }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List <Declaration> decls) { Program program = linearTypeChecker.program; // 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); // 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, 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); }
public static void Transform(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker) { List<Declaration> originalDecls = new List<Declaration>(); Program program = linearTypeChecker.program; foreach (var decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc != null && moverTypeChecker.procToActionInfo.ContainsKey(proc)) { originalDecls.Add(proc); continue; } Implementation impl = decl as Implementation; if (impl != null && moverTypeChecker.procToActionInfo.ContainsKey(impl.Proc)) { originalDecls.Add(impl); } } List<Declaration> decls = new List<Declaration>(); if (!CommandLineOptions.Clo.TrustAtomicityTypes) { MoverCheck.AddCheckers(linearTypeChecker, moverTypeChecker, decls); } OwickiGries.AddCheckers(linearTypeChecker, moverTypeChecker, decls); foreach (Declaration decl in decls) { decl.Attributes = OwickiGries.RemoveYieldsAttribute(decl.Attributes); } program.RemoveTopLevelDeclarations(x => originalDecls.Contains(x)); program.AddTopLevelDeclarations(decls); }
public static void Transform(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker) { Program program = linearTypeChecker.program; // Store the original declarations of yielding procedures, which will be removed after desugaring below. var origProc = program.TopLevelDeclarations.OfType <Procedure>().Where(p => civlTypeChecker.procToYieldingProc.ContainsKey(p)); var origImpl = program.TopLevelDeclarations.OfType <Implementation>().Where(i => civlTypeChecker.procToYieldingProc.ContainsKey(i.Proc)); List <Declaration> originalDecls = Enumerable.Union <Declaration>(origProc, origImpl).ToList(); // Commutativity checks List <Declaration> decls = new List <Declaration>(); if (!CommandLineOptions.Clo.TrustAtomicityTypes) { MoverCheck.AddCheckers(linearTypeChecker, civlTypeChecker, decls); } // Desugaring of yielding procedures YieldingProcChecker.AddCheckers(linearTypeChecker, civlTypeChecker, decls); // Linear type checks LinearTypeChecker.AddCheckers(linearTypeChecker, civlTypeChecker, decls); // Remove original declarations and add new checkers generated above program.RemoveTopLevelDeclarations(x => originalDecls.Contains(x)); program.AddTopLevelDeclarations(decls); civlTypeChecker.SubstituteBackwardAssignments(); foreach (AtomicAction atomicAction in civlTypeChecker.procToAtomicAction.Values) { program.RemoveTopLevelDeclaration(atomicAction.proc); program.RemoveTopLevelDeclaration(atomicAction.impl); } }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List<Declaration> decls) { Program program = linearTypeChecker.program; foreach (int layerNum in civlTypeChecker.AllImplementedLayerNums) { if (CommandLineOptions.Clo.TrustLayersDownto <= layerNum || layerNum <= CommandLineOptions.Clo.TrustLayersUpto) continue; MyDuplicator duplicator = new MyDuplicator(civlTypeChecker, layerNum); foreach (var proc in program.Procedures) { if (!civlTypeChecker.procToActionInfo.ContainsKey(proc)) continue; Procedure duplicateProc = duplicator.VisitProcedure(proc); decls.Add(duplicateProc); } decls.AddRange(duplicator.impls); CivlRefinement civlTransform = new CivlRefinement(linearTypeChecker, civlTypeChecker, duplicator); foreach (var impl in program.Implementations) { if (!civlTypeChecker.procToActionInfo.ContainsKey(impl.Proc) || civlTypeChecker.procToActionInfo[impl.Proc].createdAtLayerNum < layerNum) continue; Implementation duplicateImpl = duplicator.VisitImplementation(impl); civlTransform.TransformImpl(duplicateImpl); decls.Add(duplicateImpl); } decls.AddRange(civlTransform.Collect()); } }
public static void Transform(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker) { // The order in which originalDecls are computed and then *.AddCheckers are called is // apparently important. The MyDuplicator code currently does not duplicate Attributes. // Consequently, all the yield attributes are eliminated by the AddCheckers code. List<Declaration> originalDecls = new List<Declaration>(); Program program = linearTypeChecker.program; foreach (var decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc != null && QKeyValue.FindBoolAttribute(proc.Attributes, "yields")) { originalDecls.Add(proc); continue; } Implementation impl = decl as Implementation; if (impl != null && QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "yields")) { originalDecls.Add(impl); } } List<Declaration> decls = new List<Declaration>(); OwickiGries.AddCheckers(linearTypeChecker, moverTypeChecker, decls); MoverCheck.AddCheckers(linearTypeChecker, moverTypeChecker, decls); RefinementCheck.AddCheckers(linearTypeChecker, moverTypeChecker, decls); program.TopLevelDeclarations.RemoveAll(x => originalDecls.Contains(x)); program.TopLevelDeclarations.AddRange(decls); }
public SomeNoninterferenceInstrumentation( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum, Dictionary <Absy, Absy> absyMap, Dictionary <Variable, Variable> oldGlobalMap, Procedure yieldProc) { this.civlTypeChecker = civlTypeChecker; this.linearTypeChecker = linearTypeChecker; this.layerNum = layerNum; this.absyMap = absyMap; this.oldGlobalMap = oldGlobalMap; this.yieldProc = yieldProc; this.newLocalVars = new List <Variable>(); this.domainNameToLocalVar = new Dictionary <string, Variable>(); { foreach (string domainName in linearTypeChecker.linearDomains.Keys) { Variable l = linearTypeChecker.LinearDomainAvailableLocal(domainName); domainNameToLocalVar[domainName] = l; newLocalVars.Add(l); } } }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List <Declaration> decls) { Program program = linearTypeChecker.program; // 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); foreach (var procToYieldingProc in civlTypeChecker.procToYieldingProc) { if (procToYieldingProc.Value.upperLayer >= layerNum) { duplicator.VisitProcedure(procToYieldingProc.Key); } } foreach (Implementation impl in program.Implementations) { if (civlTypeChecker.procToYieldingProc.TryGetValue(impl.Proc, out var yieldingProc) && yieldingProc.upperLayer >= layerNum) { duplicator.VisitImplementation(impl); } } decls.AddRange(duplicator.Collect()); } }
public static void Transform(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker) { // The order in which originalDecls are computed and then *.AddCheckers are called is // apparently important. The MyDuplicator code currently does not duplicate Attributes. // Consequently, all the yield attributes are eliminated by the AddCheckers code. List <Declaration> originalDecls = new List <Declaration>(); Program program = linearTypeChecker.program; foreach (var decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc != null && QKeyValue.FindBoolAttribute(proc.Attributes, "yields")) { originalDecls.Add(proc); continue; } Implementation impl = decl as Implementation; if (impl != null && QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "yields")) { originalDecls.Add(impl); } } List <Declaration> decls = new List <Declaration>(); OwickiGries.AddCheckers(linearTypeChecker, moverTypeChecker, decls); MoverCheck.AddCheckers(linearTypeChecker, moverTypeChecker, decls); RefinementCheck.AddCheckers(linearTypeChecker, moverTypeChecker, decls); program.TopLevelDeclarations.RemoveAll(x => originalDecls.Contains(x)); program.TopLevelDeclarations.AddRange(decls); }
public static List <Declaration> TransformImplementations( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum, Dictionary <Absy, Absy> absyMap, Dictionary <Implementation, Implementation> implMap, HashSet <Procedure> yieldingProcs) { var yieldingProcInstrumentation = new YieldingProcInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap, implMap, yieldingProcs); foreach (var kv in implMap) { var impl = kv.Value; var newImpl = kv.Key; var proc = civlTypeChecker.procToYieldingProc[impl.Proc]; if (!(proc is MoverProc && proc.upperLayer == layerNum)) { yieldingProcInstrumentation.TransformImpl(newImpl); } } List <Declaration> decls = new List <Declaration>(yieldingProcInstrumentation.yieldCheckerDecls); foreach (Procedure proc in yieldingProcInstrumentation.asyncAndParallelCallDesugarings.Values) { decls.Add(proc); } decls.Add(yieldingProcInstrumentation.yieldProc); decls.Add(yieldingProcInstrumentation.YieldImpl()); return(decls); }
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 static void Transform(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker) { List <Declaration> originalDecls = new List <Declaration>(); Program program = linearTypeChecker.program; foreach (var decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc != null && moverTypeChecker.procToActionInfo.ContainsKey(proc)) { originalDecls.Add(proc); continue; } Implementation impl = decl as Implementation; if (impl != null && moverTypeChecker.procToActionInfo.ContainsKey(impl.Proc)) { originalDecls.Add(impl); } } List <Declaration> decls = new List <Declaration>(); if (!CommandLineOptions.Clo.TrustAtomicityTypes) { MoverCheck.AddCheckers(linearTypeChecker, moverTypeChecker, decls); } OwickiGries.AddCheckers(linearTypeChecker, moverTypeChecker, decls); foreach (Declaration decl in decls) { decl.Attributes = OwickiGries.RemoveYieldsAttribute(decl.Attributes); } program.RemoveTopLevelDeclarations(x => originalDecls.Contains(x)); program.AddTopLevelDeclarations(decls); }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List <Declaration> decls) { MoverCheck moverChecking = new MoverCheck(linearTypeChecker, civlTypeChecker, decls); // TODO: make enumeration of mover checks more efficient / elegant var regularMoverChecks = from first in civlTypeChecker.procToAtomicAction.Values from second in civlTypeChecker.procToAtomicAction.Values where first.layerRange.OverlapsWith(second.layerRange) where first.IsRightMover || second.IsLeftMover select new { first, second }; foreach (var moverCheck in regularMoverChecks) { if (moverCheck.first.IsRightMover) { moverChecking.CreateRightMoverCheckers(moverCheck.first, moverCheck.second); } if (moverCheck.second.IsLeftMover) { moverChecking.CreateLeftMoverCheckers(moverCheck.first, moverCheck.second); } } var inductiveSequentializationMoverChecks = from IS in civlTypeChecker.inductiveSequentializations from leftMover in IS.elim.Values from action in civlTypeChecker.procToAtomicAction.Values where action.layerRange.Contains(IS.inputAction.layerRange.upperLayerNum) select new { action, leftMover }; foreach (var moverCheck in inductiveSequentializationMoverChecks) { moverChecking.CreateLeftMoverCheckers(moverCheck.action, moverCheck.leftMover); } // Here we include IS abstractions foreach (var atomicAction in civlTypeChecker.AllAtomicActions.Where(a => a.IsLeftMover)) { moverChecking.CreateNonBlockingChecker(atomicAction); } // IS abstractions are marked left movers, so here we select regular atomic actions // that are not marked left mover but used as abstraction in IS. foreach (var atomicAction in civlTypeChecker.inductiveSequentializations.SelectMany(IS => IS.elim.Values) .Where(a => !a.IsLeftMover).Distinct()) { moverChecking.CreateNonBlockingChecker(atomicAction); } foreach (var introductionAction in civlTypeChecker.procToIntroductionAction.Values) { moverChecking.CreateNonBlockingChecker(introductionAction); } }
private MoverCheck(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List<Declaration> decls) { this.linearTypeChecker = linearTypeChecker; this.civlTypeChecker = civlTypeChecker; this.decls = decls; this.commutativityCheckerCache = new HashSet<Tuple<AtomicActionInfo, AtomicActionInfo>>(); this.gatePreservationCheckerCache = new HashSet<Tuple<AtomicActionInfo, AtomicActionInfo>>(); this.failurePreservationCheckerCache = new HashSet<Tuple<AtomicActionInfo, AtomicActionInfo>>(); }
private MoverCheck(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List <Declaration> decls) { this.linearTypeChecker = linearTypeChecker; this.civlTypeChecker = civlTypeChecker; this.decls = decls; this.commutativityCheckerCache = new HashSet <Tuple <AtomicActionInfo, AtomicActionInfo> >(); this.gatePreservationCheckerCache = new HashSet <Tuple <AtomicActionInfo, AtomicActionInfo> >(); this.failurePreservationCheckerCache = new HashSet <Tuple <AtomicActionInfo, AtomicActionInfo> >(); }
public YieldingProcDuplicator(CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum) { this.civlTypeChecker = civlTypeChecker; this.linearTypeChecker = linearTypeChecker; this.layerNum = layerNum; this.procMap = new Dictionary <Procedure, Procedure>(); this.absyMap = new Dictionary <Absy, Absy>(); this.implMap = new Dictionary <Implementation, Implementation>(); this.yieldingProcs = new HashSet <Procedure>(); }
public YieldingProcDuplicator(CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum) { this.civlTypeChecker = civlTypeChecker; this.linearTypeChecker = linearTypeChecker; this.layerNum = layerNum; this.procToDuplicate = new Dictionary <Procedure, Procedure>(); this.absyMap = new Dictionary <Absy, Absy>(); this.yieldingProcs = new HashSet <Procedure>(); this.asyncCallPreconditionCheckers = new Dictionary <string, Procedure>(); }
public LinearPermissionInstrumentation( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum, Dictionary <Absy, Absy> absyMap) { this.civlTypeChecker = civlTypeChecker; this.linearTypeChecker = linearTypeChecker; this.layerNum = layerNum; this.absyMap = absyMap; this.domainNameToHoleVar = new Dictionary <string, Variable>(); this.localVarMap = new Dictionary <Variable, Variable>(); }
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()); } }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker, List <Declaration> decls) { if (moverTypeChecker.procToActionInfo.Count == 0) { return; } Dictionary <int, HashSet <ActionInfo> > pools = new Dictionary <int, HashSet <ActionInfo> >(); foreach (ActionInfo action in moverTypeChecker.procToActionInfo.Values) { foreach (int phaseNum in action.callerPhaseNums) { if (!pools.ContainsKey(phaseNum)) { pools[phaseNum] = new HashSet <ActionInfo>(); } pools[phaseNum].Add(action); } } Program program = moverTypeChecker.program; MoverCheck moverChecking = new MoverCheck(linearTypeChecker, moverTypeChecker, decls); foreach (int phaseNum in pools.Keys) { foreach (ActionInfo first in pools[phaseNum]) { Debug.Assert(first.moverType != MoverType.Top); if (first.moverType == MoverType.Atomic) { continue; } foreach (ActionInfo second in pools[phaseNum]) { if (first.IsRightMover) { moverChecking.CreateCommutativityChecker(program, first, second); moverChecking.CreateGatePreservationChecker(program, second, first); } if (first.IsLeftMover) { moverChecking.CreateCommutativityChecker(program, second, first); moverChecking.CreateGatePreservationChecker(program, first, second); moverChecking.CreateFailurePreservationChecker(program, second, first); } } } } }
private static List<Expr> PendingAsyncLinearParams(LinearTypeChecker linearTypeChecker, LinearDomain domain, AtomicAction pendingAsync, IdentifierExpr pa) { var pendingAsyncLinearParams = new List<Expr>(); for (int i = 0; i < pendingAsync.proc.InParams.Count; i++) { var inParam = pendingAsync.proc.InParams[i]; if (linearTypeChecker.FindDomainName(inParam) == domain.domainName && InKinds.Contains(linearTypeChecker.FindLinearKind(inParam))) { var pendingAsyncParam = ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.selectors[i], pa); pendingAsyncLinearParams.Add(pendingAsyncParam); } } return pendingAsyncLinearParams; }
public static void Transform(CivlTypeChecker civlTypeChecker) { var linearTypeChecker = civlTypeChecker.linearTypeChecker; Program program = linearTypeChecker.program; // Store the original declarations of yielding procedures, which will be removed after desugaring below. var origProc = program.TopLevelDeclarations.OfType <Procedure>() .Where(p => civlTypeChecker.procToYieldingProc.ContainsKey(p)); var origImpl = program.TopLevelDeclarations.OfType <Implementation>() .Where(i => civlTypeChecker.procToYieldingProc.ContainsKey(i.Proc)); List <Declaration> originalDecls = Enumerable.Union <Declaration>(origProc, origImpl).ToList(); // Commutativity checks List <Declaration> decls = new List <Declaration>(); if (!CommandLineOptions.Clo.TrustMoverTypes) { MoverCheck.AddCheckers(civlTypeChecker, decls); } // Desugaring of yielding procedures YieldingProcChecker.AddCheckers(civlTypeChecker, decls); // Linear type checks LinearTypeChecker.AddCheckers(civlTypeChecker, decls); if (!CommandLineOptions.Clo.TrustInductiveSequentialization) { InductiveSequentializationChecker.AddCheckers(civlTypeChecker); } PendingAsyncChecker.AddCheckers(civlTypeChecker); foreach (AtomicAction action in civlTypeChecker.procToAtomicAction.Values.Union(civlTypeChecker .procToIsAbstraction.Values)) { action.AddTriggerAssumes(program); } // Remove original declarations and add new checkers generated above program.RemoveTopLevelDeclarations(x => originalDecls.Contains(x)); program.AddTopLevelDeclarations(decls); BackwardAssignmentSubstituter.SubstituteBackwardAssignments(civlTypeChecker.procToAtomicAction.Values); linearTypeChecker.EraseLinearAnnotations(); }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker, List<Declaration> decls) { if (moverTypeChecker.procToActionInfo.Count == 0) return; Dictionary<int, HashSet<ActionInfo>> pools = new Dictionary<int, HashSet<ActionInfo>>(); foreach (ActionInfo action in moverTypeChecker.procToActionInfo.Values) { foreach (int phaseNum in action.callerPhaseNums) { if (!pools.ContainsKey(phaseNum)) { pools[phaseNum] = new HashSet<ActionInfo>(); } pools[phaseNum].Add(action); } } Program program = moverTypeChecker.program; MoverCheck moverChecking = new MoverCheck(linearTypeChecker, moverTypeChecker, decls); foreach (int phaseNum in pools.Keys) { foreach (ActionInfo first in pools[phaseNum]) { Debug.Assert(first.moverType != MoverType.Top); if (first.moverType == MoverType.Atomic) continue; foreach (ActionInfo second in pools[phaseNum]) { if (first.IsRightMover) { moverChecking.CreateCommutativityChecker(program, first, second); moverChecking.CreateGatePreservationChecker(program, second, first); } if (first.IsLeftMover) { moverChecking.CreateCommutativityChecker(program, second, first); moverChecking.CreateGatePreservationChecker(program, first, second); moverChecking.CreateFailurePreservationChecker(program, second, first); } } } } }
public CivlRefinement(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, MyDuplicator duplicator) { this.linearTypeChecker = linearTypeChecker; this.civlTypeChecker = civlTypeChecker; this.absyMap = duplicator.absyMap; this.layerNum = duplicator.layerNum; this.implMap = duplicator.implMap; this.yieldingProcs = duplicator.yieldingProcs; Program program = linearTypeChecker.program; globalMods = new List<IdentifierExpr>(); foreach (Variable g in civlTypeChecker.SharedVariables) { globalMods.Add(Expr.Ident(g)); } asyncAndParallelCallDesugarings = new Dictionary<string, Procedure>(); yieldCheckerProcs = new List<Procedure>(); yieldCheckerImpls = new List<Implementation>(); yieldProc = null; }
public static List <Declaration> TransformImplementations( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, int layerNum, Dictionary <Absy, Absy> absyMap, HashSet <Procedure> yieldingProcs) { var linearHelper = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap); var yieldingProcInstrumentation = new YieldingProcInstrumentation( civlTypeChecker, linearTypeChecker, linearHelper, layerNum, absyMap, yieldingProcs); foreach (var impl in absyMap.Keys.OfType <Implementation>()) { // Add disjointness assumptions at beginning, loop headers, and after each call or parallel call. // These are added for each duplicate implementation of yielding procedures. // Disjointness assumptions after yields are added inside TransformImpl which is called for // all implementations except for a mover procedure at its disappearing layer. // But this is fine because a mover procedure at its disappearing layer does not have a yield in it. linearHelper.AddDisjointnessAssumptions(impl, yieldingProcs); var originalImpl = absyMap[impl] as Implementation; var proc = civlTypeChecker.procToYieldingProc[originalImpl.Proc]; if (!(proc is MoverProc && proc.upperLayer == layerNum)) { yieldingProcInstrumentation.TransformImpl(originalImpl, impl); } } List <Declaration> decls = new List <Declaration>(yieldingProcInstrumentation.noninterferenceCheckerDecls); foreach (Procedure proc in yieldingProcInstrumentation.parallelCallPreconditionCheckers.Values) { decls.Add(proc); } decls.Add(yieldingProcInstrumentation.wrapperNoninterferenceCheckerProc); decls.Add(yieldingProcInstrumentation.WrapperNoninterferenceCheckerImpl()); return(decls); }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List <Declaration> decls) { if (civlTypeChecker.procToAtomicAction.Count == 0) { return; } MoverCheck moverChecking = new MoverCheck(linearTypeChecker, civlTypeChecker, decls); foreach (int layer in civlTypeChecker.allAtomicActionLayers) { var pool = civlTypeChecker.procToAtomicAction.Values.Where(a => a.layerRange.Contains(layer)); var moverChecks = from first in pool from second in pool where first.moverType != MoverType.Atomic select new { First = first, Second = second }; foreach (var moverCheck in moverChecks) { var first = moverCheck.First.layerToActionCopy[layer]; var second = moverCheck.Second.layerToActionCopy[layer]; if (moverCheck.First.IsRightMover) { moverChecking.CreateCommutativityChecker(first, second); moverChecking.CreateGatePreservationChecker(second, first); } if (moverCheck.First.IsLeftMover) { moverChecking.CreateCommutativityChecker(second, first); moverChecking.CreateGatePreservationChecker(first, second); moverChecking.CreateFailurePreservationChecker(second, first); } } foreach (AtomicAction atomicAction in pool.Where(a => a.IsLeftMover)) { moverChecking.CreateNonBlockingChecker(atomicAction.layerToActionCopy[layer]); } } }
public SomeNoninterferenceInstrumentation( CivlTypeChecker civlTypeChecker, LinearTypeChecker linearTypeChecker, LinearPermissionInstrumentation linearPermissionInstrumentation, Dictionary <Variable, Variable> oldGlobalMap, Procedure yieldProc) { this.civlTypeChecker = civlTypeChecker; this.linearTypeChecker = linearTypeChecker; this.linearPermissionInstrumentation = linearPermissionInstrumentation; this.oldGlobalMap = oldGlobalMap; this.yieldProc = yieldProc; this.newLocalVars = new List <Variable>(); this.domainNameToHoleVar = new Dictionary <string, Variable>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { Variable l = linearTypeChecker.LinearDomainAvailableLocal(domainName); domainNameToHoleVar[domainName] = l; newLocalVars.Add(l); } }
public static void Transform(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker) { List <Declaration> originalDecls = new List <Declaration>(); Program program = linearTypeChecker.program; foreach (var decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc != null && civlTypeChecker.procToActionInfo.ContainsKey(proc)) { originalDecls.Add(proc); continue; } Implementation impl = decl as Implementation; if (impl != null && civlTypeChecker.procToActionInfo.ContainsKey(impl.Proc)) { originalDecls.Add(impl); } } List <Declaration> decls = new List <Declaration>(); if (!CommandLineOptions.Clo.TrustAtomicityTypes) { MoverCheck.AddCheckers(linearTypeChecker, civlTypeChecker, decls); } CivlRefinement.AddCheckers(linearTypeChecker, civlTypeChecker, decls); foreach (AtomicActionInfo info in civlTypeChecker.procToActionInfo.Values.Where(x => x is AtomicActionInfo)) { decls.AddRange(info.triggerFuns.Values); } foreach (Declaration decl in decls) { CivlAttributes.RemoveYieldsAttribute(decl); } program.RemoveTopLevelDeclarations(x => originalDecls.Contains(x)); program.AddTopLevelDeclarations(decls); }
public static void Transform(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker) { List<Declaration> originalDecls = new List<Declaration>(); Program program = linearTypeChecker.program; foreach (var decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc != null && civlTypeChecker.procToActionInfo.ContainsKey(proc)) { originalDecls.Add(proc); continue; } Implementation impl = decl as Implementation; if (impl != null && civlTypeChecker.procToActionInfo.ContainsKey(impl.Proc)) { originalDecls.Add(impl); } } List<Declaration> decls = new List<Declaration>(); if (!CommandLineOptions.Clo.TrustAtomicityTypes) { MoverCheck.AddCheckers(linearTypeChecker, civlTypeChecker, decls); } CivlRefinement.AddCheckers(linearTypeChecker, civlTypeChecker, decls); foreach (AtomicActionInfo info in civlTypeChecker.procToActionInfo.Values.Where(x => x is AtomicActionInfo)) { decls.AddRange(info.triggerFuns.Values); } foreach (Declaration decl in decls) { CivlAttributes.RemoveYieldsAttribute(decl); } program.RemoveTopLevelDeclarations(x => originalDecls.Contains(x)); program.AddTopLevelDeclarations(decls); }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker, List<Declaration> decls) { Program program = linearTypeChecker.program; foreach (int layerNum in moverTypeChecker.AllCreatedLayerNums.Except(new int[] { moverTypeChecker.leastUnimplementedLayerNum })) { if (CommandLineOptions.Clo.TrustLayersDownto <= layerNum || layerNum <= CommandLineOptions.Clo.TrustLayersUpto) continue; MyDuplicator duplicator = new MyDuplicator(moverTypeChecker, layerNum); foreach (var proc in program.Procedures) { if (!moverTypeChecker.procToActionInfo.ContainsKey(proc)) continue; Procedure duplicateProc = duplicator.VisitProcedure(proc); decls.Add(duplicateProc); } decls.AddRange(duplicator.impls); OwickiGries ogTransform = new OwickiGries(linearTypeChecker, moverTypeChecker, duplicator); foreach (var impl in program.Implementations) { if (!moverTypeChecker.procToActionInfo.ContainsKey(impl.Proc) || moverTypeChecker.procToActionInfo[impl.Proc].createdAtLayerNum < layerNum) continue; Implementation duplicateImpl = duplicator.VisitImplementation(impl); ogTransform.TransformImpl(duplicateImpl); decls.Add(duplicateImpl); } decls.AddRange(ogTransform.Collect()); } }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker, List<Declaration> decls) { }
/// <summary> /// Resolves and type checks the given Boogie program. Any errors are reported to the /// console. Returns: /// - Done if no errors occurred, and command line specified no resolution or no type checking. /// - ResolutionError if a resolution error occurred /// - TypeCheckingError if a type checking error occurred /// - ResolvedAndTypeChecked if both resolution and type checking succeeded /// </summary> public static PipelineOutcome ResolveAndTypecheck(Program program, string bplFileName, out LinearTypeChecker linearTypeChecker, out CivlTypeChecker civlTypeChecker) { Contract.Requires(program != null); Contract.Requires(bplFileName != null); linearTypeChecker = null; civlTypeChecker = null; // ---------- Resolve ------------------------------------------------------------ if (CommandLineOptions.Clo.NoResolve) { return PipelineOutcome.Done; } int errorCount = program.Resolve(); if (errorCount != 0) { Console.WriteLine("{0} name resolution errors detected in {1}", errorCount, GetFileNameForConsole(bplFileName)); return PipelineOutcome.ResolutionError; } // ---------- Type check ------------------------------------------------------------ if (CommandLineOptions.Clo.NoTypecheck) { return PipelineOutcome.Done; } errorCount = program.Typecheck(); if (errorCount != 0) { Console.WriteLine("{0} type checking errors detected in {1}", errorCount, GetFileNameForConsole(bplFileName)); return PipelineOutcome.TypeCheckingError; } if (PolymorphismChecker.IsMonomorphic(program)) { CommandLineOptions.Clo.TypeEncodingMethod = CommandLineOptions.TypeEncoding.Monomorphic; } CollectModSets(program); civlTypeChecker = new CivlTypeChecker(program); civlTypeChecker.TypeCheck(); if (civlTypeChecker.errorCount != 0) { Console.WriteLine("{0} type checking errors detected in {1}", civlTypeChecker.errorCount, GetFileNameForConsole(bplFileName)); return PipelineOutcome.TypeCheckingError; } linearTypeChecker = new LinearTypeChecker(program); linearTypeChecker.TypeCheck(); if (linearTypeChecker.errorCount == 0) { linearTypeChecker.Transform(); } else { Console.WriteLine("{0} type checking errors detected in {1}", linearTypeChecker.errorCount, GetFileNameForConsole(bplFileName)); return PipelineOutcome.TypeCheckingError; } if (CommandLineOptions.Clo.PrintFile != null && CommandLineOptions.Clo.PrintDesugarings) { // if PrintDesugaring option is engaged, print the file here, after resolution and type checking PrintBplFile(CommandLineOptions.Clo.PrintFile, program, true, true, CommandLineOptions.Clo.PrettyPrint); } return PipelineOutcome.ResolvedAndTypeChecked; }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List<Declaration> decls) { if (civlTypeChecker.procToActionInfo.Count == 0) return; List<ActionInfo> sortedByCreatedLayerNum = new List<ActionInfo>(civlTypeChecker.procToActionInfo.Values.Where(x => x is AtomicActionInfo && !x.isExtern)); sortedByCreatedLayerNum.Sort((x, y) => { return (x.createdAtLayerNum == y.createdAtLayerNum) ? 0 : (x.createdAtLayerNum < y.createdAtLayerNum) ? -1 : 1; }); List<ActionInfo> sortedByAvailableUptoLayerNum = new List<ActionInfo>(civlTypeChecker.procToActionInfo.Values.Where(x => x is AtomicActionInfo && !x.isExtern)); sortedByAvailableUptoLayerNum.Sort((x, y) => { return (x.availableUptoLayerNum == y.availableUptoLayerNum) ? 0 : (x.availableUptoLayerNum < y.availableUptoLayerNum) ? -1 : 1; }); Dictionary<int, HashSet<AtomicActionInfo>> pools = new Dictionary<int, HashSet<AtomicActionInfo>>(); int indexIntoSortedByCreatedLayerNum = 0; int indexIntoSortedByAvailableUptoLayerNum = 0; HashSet<AtomicActionInfo> currPool = new HashSet<AtomicActionInfo>(); while (indexIntoSortedByCreatedLayerNum < sortedByCreatedLayerNum.Count) { var currLayerNum = sortedByCreatedLayerNum[indexIntoSortedByCreatedLayerNum].createdAtLayerNum; pools[currLayerNum] = new HashSet<AtomicActionInfo>(currPool); while (indexIntoSortedByCreatedLayerNum < sortedByCreatedLayerNum.Count) { var actionInfo = sortedByCreatedLayerNum[indexIntoSortedByCreatedLayerNum] as AtomicActionInfo; if (actionInfo.createdAtLayerNum > currLayerNum) break; pools[currLayerNum].Add(actionInfo); indexIntoSortedByCreatedLayerNum++; } while (indexIntoSortedByAvailableUptoLayerNum < sortedByAvailableUptoLayerNum.Count) { var actionInfo = sortedByAvailableUptoLayerNum[indexIntoSortedByAvailableUptoLayerNum] as AtomicActionInfo; if (actionInfo.availableUptoLayerNum > currLayerNum) break; pools[currLayerNum].Remove(actionInfo); indexIntoSortedByAvailableUptoLayerNum++; } currPool = pools[currLayerNum]; } // No atomic action has mover type Top Debug.Assert(pools.All(l => l.Value.All(a => a.moverType != MoverType.Top))); Program program = civlTypeChecker.program; MoverCheck moverChecking = new MoverCheck(linearTypeChecker, civlTypeChecker, decls); var moverChecks = from layer in pools.Keys from first in pools[layer] from second in pools[layer] where first.moverType != MoverType.Atomic select new { First = first, Second = second }; foreach (var moverCheck in moverChecks) { var first = moverCheck.First; var second = moverCheck.Second; if (first.IsRightMover) { moverChecking.CreateCommutativityChecker(program, first, second); moverChecking.CreateGatePreservationChecker(program, second, first); } if (first.IsLeftMover) { moverChecking.CreateCommutativityChecker(program, second, first); moverChecking.CreateGatePreservationChecker(program, first, second); moverChecking.CreateFailurePreservationChecker(program, second, first); } } foreach (AtomicActionInfo atomicActionInfo in sortedByCreatedLayerNum) { if (atomicActionInfo.IsLeftMover && atomicActionInfo.hasAssumeCmd) { moverChecking.CreateNonBlockingChecker(program, atomicActionInfo); } } }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker, List <Declaration> decls) { }
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 <YieldInfo> yieldInfos = null; if (decl is Implementation impl) { 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)) { 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 { 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.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 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(Token.NoToken, 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(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 }); }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker, List <Declaration> decls) { if (moverTypeChecker.procToActionInfo.Count == 0) { return; } List <ActionInfo> sortedByCreatedLayerNum = new List <ActionInfo>(moverTypeChecker.procToActionInfo.Values.Where(x => x is AtomicActionInfo)); sortedByCreatedLayerNum.Sort((x, y) => { return((x.createdAtLayerNum == y.createdAtLayerNum) ? 0 : (x.createdAtLayerNum < y.createdAtLayerNum) ? -1 : 1); }); List <ActionInfo> sortedByAvailableUptoLayerNum = new List <ActionInfo>(moverTypeChecker.procToActionInfo.Values.Where(x => x is AtomicActionInfo)); sortedByAvailableUptoLayerNum.Sort((x, y) => { return((x.availableUptoLayerNum == y.availableUptoLayerNum) ? 0 : (x.availableUptoLayerNum < y.availableUptoLayerNum) ? -1 : 1); }); Dictionary <int, HashSet <AtomicActionInfo> > pools = new Dictionary <int, HashSet <AtomicActionInfo> >(); int indexIntoSortedByCreatedLayerNum = 0; int indexIntoSortedByAvailableUptoLayerNum = 0; HashSet <AtomicActionInfo> currPool = new HashSet <AtomicActionInfo>(); while (indexIntoSortedByCreatedLayerNum < sortedByCreatedLayerNum.Count) { var currLayerNum = sortedByCreatedLayerNum[indexIntoSortedByCreatedLayerNum].createdAtLayerNum; pools[currLayerNum] = new HashSet <AtomicActionInfo>(currPool); while (indexIntoSortedByCreatedLayerNum < sortedByCreatedLayerNum.Count) { var actionInfo = sortedByCreatedLayerNum[indexIntoSortedByCreatedLayerNum] as AtomicActionInfo; if (actionInfo.createdAtLayerNum > currLayerNum) { break; } pools[currLayerNum].Add(actionInfo); indexIntoSortedByCreatedLayerNum++; } while (indexIntoSortedByAvailableUptoLayerNum < sortedByAvailableUptoLayerNum.Count) { var actionInfo = sortedByAvailableUptoLayerNum[indexIntoSortedByAvailableUptoLayerNum] as AtomicActionInfo; if (actionInfo.availableUptoLayerNum > currLayerNum) { break; } pools[currLayerNum].Remove(actionInfo); indexIntoSortedByAvailableUptoLayerNum++; } currPool = pools[currLayerNum]; } Program program = moverTypeChecker.program; MoverCheck moverChecking = new MoverCheck(linearTypeChecker, moverTypeChecker, decls); foreach (int layerNum in pools.Keys) { foreach (AtomicActionInfo first in pools[layerNum]) { Debug.Assert(first.moverType != MoverType.Top); if (first.moverType == MoverType.Atomic) { continue; } foreach (AtomicActionInfo second in pools[layerNum]) { if (first.IsRightMover) { moverChecking.CreateCommutativityChecker(program, first, second); moverChecking.CreateGatePreservationChecker(program, second, first); } if (first.IsLeftMover) { moverChecking.CreateCommutativityChecker(program, second, first); moverChecking.CreateGatePreservationChecker(program, first, second); moverChecking.CreateFailurePreservationChecker(program, second, first); } } } } foreach (ActionInfo actionInfo in moverTypeChecker.procToActionInfo.Values) { AtomicActionInfo atomicActionInfo = actionInfo as AtomicActionInfo; if (atomicActionInfo != null && atomicActionInfo.IsLeftMover && atomicActionInfo.hasAssumeCmd) { moverChecking.CreateNonBlockingChecker(program, atomicActionInfo); } } }
public OwickiGries(LinearTypeChecker linearTypeChecker, Dictionary<Absy, Absy> absyMap, int phaseNum, List<Declaration> decls) { this.linearTypeChecker = linearTypeChecker; this.absyMap = absyMap; this.phaseNum = phaseNum; this.decls = decls; Program program = linearTypeChecker.program; globalMods = new List<IdentifierExpr>(); foreach (Variable g in program.GlobalVariables()) { globalMods.Add(new IdentifierExpr(Token.NoToken, g)); } asyncAndParallelCallDesugarings = new Dictionary<string, Procedure>(); yieldCheckerProcs = new List<Procedure>(); yieldCheckerImpls = new List<Implementation>(); yieldProc = null; }
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 void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List <Declaration> decls) { if (civlTypeChecker.procToActionInfo.Count == 0) { return; } List <ActionInfo> sortedByCreatedLayerNum = new List <ActionInfo>(civlTypeChecker.procToActionInfo.Values.Where(x => x is AtomicActionInfo && !x.isExtern)); sortedByCreatedLayerNum.Sort((x, y) => { return((x.createdAtLayerNum == y.createdAtLayerNum) ? 0 : (x.createdAtLayerNum < y.createdAtLayerNum) ? -1 : 1); }); List <ActionInfo> sortedByAvailableUptoLayerNum = new List <ActionInfo>(civlTypeChecker.procToActionInfo.Values.Where(x => x is AtomicActionInfo && !x.isExtern)); sortedByAvailableUptoLayerNum.Sort((x, y) => { return((x.availableUptoLayerNum == y.availableUptoLayerNum) ? 0 : (x.availableUptoLayerNum < y.availableUptoLayerNum) ? -1 : 1); }); Dictionary <int, HashSet <AtomicActionInfo> > pools = new Dictionary <int, HashSet <AtomicActionInfo> >(); int indexIntoSortedByCreatedLayerNum = 0; int indexIntoSortedByAvailableUptoLayerNum = 0; HashSet <AtomicActionInfo> currPool = new HashSet <AtomicActionInfo>(); while (indexIntoSortedByCreatedLayerNum < sortedByCreatedLayerNum.Count) { var currLayerNum = sortedByCreatedLayerNum[indexIntoSortedByCreatedLayerNum].createdAtLayerNum; pools[currLayerNum] = new HashSet <AtomicActionInfo>(currPool); while (indexIntoSortedByCreatedLayerNum < sortedByCreatedLayerNum.Count) { var actionInfo = sortedByCreatedLayerNum[indexIntoSortedByCreatedLayerNum] as AtomicActionInfo; if (actionInfo.createdAtLayerNum > currLayerNum) { break; } pools[currLayerNum].Add(actionInfo); indexIntoSortedByCreatedLayerNum++; } while (indexIntoSortedByAvailableUptoLayerNum < sortedByAvailableUptoLayerNum.Count) { var actionInfo = sortedByAvailableUptoLayerNum[indexIntoSortedByAvailableUptoLayerNum] as AtomicActionInfo; if (actionInfo.availableUptoLayerNum > currLayerNum) { break; } pools[currLayerNum].Remove(actionInfo); indexIntoSortedByAvailableUptoLayerNum++; } currPool = pools[currLayerNum]; } // No atomic action has mover type Top Debug.Assert(pools.All(l => l.Value.All(a => a.moverType != MoverType.Top))); Program program = civlTypeChecker.program; MoverCheck moverChecking = new MoverCheck(linearTypeChecker, civlTypeChecker, decls); var moverChecks = from layer in pools.Keys from first in pools[layer] from second in pools[layer] where first.moverType != MoverType.Atomic select new { First = first, Second = second }; foreach (var moverCheck in moverChecks) { var first = moverCheck.First; var second = moverCheck.Second; if (first.IsRightMover) { moverChecking.CreateCommutativityChecker(program, first, second); moverChecking.CreateGatePreservationChecker(program, second, first); } if (first.IsLeftMover) { moverChecking.CreateCommutativityChecker(program, second, first); moverChecking.CreateGatePreservationChecker(program, first, second); moverChecking.CreateFailurePreservationChecker(program, second, first); } } foreach (AtomicActionInfo atomicActionInfo in sortedByCreatedLayerNum) { if (atomicActionInfo.IsLeftMover && atomicActionInfo.hasAssumeCmd) { moverChecking.CreateNonBlockingChecker(program, atomicActionInfo); } } }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker, List<Declaration> decls) { Program program = linearTypeChecker.program; foreach (int phaseNum in moverTypeChecker.assertionPhaseNums) { MyDuplicator duplicator = new MyDuplicator(moverTypeChecker, phaseNum); List<Implementation> impls = new List<Implementation>(); List<Procedure> procs = new List<Procedure>(); foreach (var decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc == null || !QKeyValue.FindBoolAttribute(proc.Attributes, "yields")) continue; Procedure duplicateProc = duplicator.VisitProcedure(proc); procs.Add(duplicateProc); if (moverTypeChecker.procToActionInfo.ContainsKey(proc) && moverTypeChecker.procToActionInfo[proc].phaseNum < phaseNum) { duplicateProc.Attributes = OwickiGries.RemoveYieldsAttribute(duplicateProc.Attributes); program.GlobalVariables().Iter(x => duplicateProc.Modifies.Add(new IdentifierExpr(Token.NoToken, x))); CodeExpr action = (CodeExpr)duplicator.VisitCodeExpr(moverTypeChecker.procToActionInfo[proc].thisAction); Implementation impl = new Implementation(Token.NoToken, duplicateProc.Name, proc.TypeParameters, proc.InParams, proc.OutParams, new List<Variable>(), action.Blocks); impl.Proc = duplicateProc; impl.Proc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); impl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); impls.Add(impl); } } foreach (var decl in program.TopLevelDeclarations) { Implementation impl = decl as Implementation; if (impl == null || !QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "yields") || (moverTypeChecker.procToActionInfo.ContainsKey(impl.Proc) && moverTypeChecker.procToActionInfo[impl.Proc].phaseNum < phaseNum)) continue; Implementation duplicateImpl = duplicator.VisitImplementation(impl); impls.Add(duplicateImpl); } Dictionary<Absy, Absy> reverseAbsyMap = new Dictionary<Absy, Absy>(); foreach (Absy key in duplicator.absyMap.Keys) { reverseAbsyMap[duplicator.absyMap[key]] = key; } OwickiGries ogTransform = new OwickiGries(linearTypeChecker, reverseAbsyMap, phaseNum, decls); ogTransform.Transform(impls, procs); } }