public override Procedure VisitProcedure(Procedure node) { Debug.Assert(civlTypeChecker.procToYieldingProc.ContainsKey(node)); if (!procToDuplicate.ContainsKey(node)) { YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[node]; Debug.Assert(layerNum <= yieldingProc.upperLayer); Procedure proc = (Procedure)node.Clone(); proc.Name = $"{node.Name}_{layerNum}"; proc.InParams = this.VisitVariableSeq(node.InParams); proc.OutParams = this.VisitVariableSeq(node.OutParams); proc.Requires = this.VisitRequiresSeq(node.Requires); proc.Ensures = this.VisitEnsuresSeq(node.Ensures); if (yieldingProc is MoverProc moverProc && yieldingProc.upperLayer == layerNum) { proc.Modifies = moverProc.modifiedGlobalVars.Select(g => Expr.Ident(g)).ToList(); } else { proc.Modifies = civlTypeChecker.GlobalVariables.Select(v => Expr.Ident(v)).ToList(); yieldingProcs.Add(proc); } procToDuplicate[node] = proc; absyMap[proc] = node; }
private int CallCmdLabel(CallCmd callCmd) { if (@base.civlTypeChecker.procToIntroductionProc.ContainsKey(callCmd.Proc)) { return(I); } YieldingProc callee = @base.civlTypeChecker.procToYieldingProc[callCmd.Proc]; if (callCmd.IsAsync) { if (callee is ActionProc && !callCmd.HasAttribute(CivlAttributes.SYNC)) { return(L); } if (callee.upperLayer < currLayerNum || (callee.upperLayer == currLayerNum && callee is MoverProc)) { return(MoverTypeToLabel(callee.moverType)); } return(L); } else { if (callee.upperLayer < currLayerNum || (callee.upperLayer == currLayerNum && callee is MoverProc)) { return(MoverTypeToLabel(callee.moverType)); } return(Y); } }
private int CallCmdLabel(CallCmd callCmd) { if ([email protected](callCmd.Proc)) { return(P); } YieldingProc callee = @base.civlTypeChecker.procToYieldingProc[callCmd.Proc]; if (callCmd.IsAsync) { if ((currLayerNum < yieldingProc.upperLayer && currLayerNum > callee.upperLayer) || (currLayerNum == yieldingProc.upperLayer && callee.upperLayer < yieldingProc.upperLayer)) { return(MoverTypeToLabel(callee.moverType)); } return(L); } else { if (callee.upperLayer < currLayerNum || (callee.upperLayer == currLayerNum && callee is MoverProc)) { return(MoverTypeToLabel(callee.moverType)); } return(Y); } }
private string CallCmdLabel(CallCmd callCmd) { if (@base.civlTypeChecker.procToIntroductionAction.ContainsKey(callCmd.Proc) || @base.civlTypeChecker.procToLemmaProc.ContainsKey(callCmd.Proc)) { return(I); } if (@base.civlTypeChecker.procToYieldInvariant.ContainsKey(callCmd.Proc)) { return(@base.civlTypeChecker.procToYieldInvariant[callCmd.Proc].LayerNum == currLayerNum ? Y : P); } YieldingProc callee = @base.civlTypeChecker.procToYieldingProc[callCmd.Proc]; if (callCmd.IsAsync) { return(L); } if (callee is MoverProc && callee.upperLayer == currLayerNum) { return(MoverTypeToLabel(callee.moverType)); } if (callee is ActionProc actionProc && callee.upperLayer < currLayerNum) { return(MoverTypeToLabel(actionProc.RefinedActionAtLayer(currLayerNum).moverType)); } return(Y); }
private void TransformImpl(Implementation originalImpl, Implementation impl) { // initialize globalSnapshotInstrumentation globalSnapshotInstrumentation = new GlobalSnapshotInstrumentation(civlTypeChecker); // initialize refinementInstrumentation YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[originalImpl.Proc]; if (yieldingProc.upperLayer == this.layerNum) { if (yieldingProc is ActionProc) { refinementInstrumentation = new ActionRefinementInstrumentation( civlTypeChecker, impl, originalImpl, globalSnapshotInstrumentation.OldGlobalMap); } else { refinementInstrumentation = new SkipRefinementInstrumentation( civlTypeChecker, yieldingProc, globalSnapshotInstrumentation.OldGlobalMap); } } else { refinementInstrumentation = new RefinementInstrumentation(); } var allYieldPredicates = CollectYields(impl); // initialize noninterferenceInstrumentation if (CommandLineOptions.Clo.TrustNonInterference) { noninterferenceInstrumentation = new NoneNoninterferenceInstrumentation(); } else { noninterferenceCheckerDecls.AddRange( NoninterferenceChecker.CreateNoninterferenceCheckers(civlTypeChecker, linearTypeChecker, layerNum, absyMap, impl, allYieldPredicates)); noninterferenceInstrumentation = new SomeNoninterferenceInstrumentation( civlTypeChecker, linearTypeChecker, linearPermissionInstrumentation, globalSnapshotInstrumentation.OldGlobalMap, wrapperNoninterferenceCheckerProc); } DesugarConcurrency(impl, allYieldPredicates); impl.LocVars.AddRange(globalSnapshotInstrumentation.NewLocalVars); impl.LocVars.AddRange(refinementInstrumentation.NewLocalVars); impl.LocVars.AddRange(noninterferenceInstrumentation.NewLocalVars); }
public PerLayerYieldSufficiencyTypeChecker(CivlTypeChecker civlTypeChecker, YieldingProc yieldingProc, Implementation impl, int currLayerNum, Graph <Block> implGraph, Graph <MoverProc> moverProcedureCallGraph) { this.civlTypeChecker = civlTypeChecker; this.yieldingProc = yieldingProc; this.impl = impl; this.currLayerNum = currLayerNum; this.implGraph = implGraph; this.moverProcedureCallGraph = moverProcedureCallGraph; }
public override Procedure VisitProcedure(Procedure node) { if (!civlTypeChecker.procToYieldingProc.ContainsKey(node)) { return(node); } if (!procMap.ContainsKey(node)) { YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[node]; if (layerNum > yieldingProc.upperLayer) { if (yieldingProc is ActionProc actionProc) { // yielding procedure already transformed to atomic action var action = actionProc.refinedAction; if (action.layerRange.Contains(layerNum)) { return(action.layerToActionCopy[layerNum].proc); } else { return(node); } } else if (yieldingProc is SkipProc) { // (calls to) skip procedures do not completely disappear because of output variables return(procToSkipProcDummy[yieldingProc.proc]); } else if (yieldingProc is MoverProc) { // mover procedure does not exist on this layer any more return(node); } } Procedure proc = (Procedure)node.Clone(); proc.Name = $"{node.Name}_{layerNum}"; proc.InParams = this.VisitVariableSeq(node.InParams); proc.OutParams = this.VisitVariableSeq(node.OutParams); proc.Requires = this.VisitRequiresSeq(node.Requires); proc.Ensures = this.VisitEnsuresSeq(node.Ensures); if (yieldingProc is MoverProc moverProc && yieldingProc.upperLayer == layerNum) { proc.Modifies = moverProc.modifiedGlobalVars.Select(g => Expr.Ident(g)).ToList(); } else { proc.Modifies = civlTypeChecker.sharedVariableIdentifiers; yieldingProcs.Add(proc); } procMap[node] = proc; }
public PerLayerYieldTypeChecker(YieldTypeChecker @base, YieldingProc yieldingProc, Implementation impl, int currLayerNum, Graph <Block> implGraph) { this.@base = @base; this.yieldingProc = yieldingProc; this.impl = impl; this.currLayerNum = currLayerNum; this.implGraph = implGraph; this.initialState = impl.Blocks[0]; this.finalStates = new HashSet <Absy>(); this.implEdges = new List <Tuple <Absy, int, Absy> >(); }
public override Procedure VisitProcedure(Procedure node) { if (!civlTypeChecker.procToYieldingProc.ContainsKey(node)) { return(node); } if (!procMap.ContainsKey(node)) { YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[node]; if (layerNum > yieldingProc.upperLayer) { if (yieldingProc is ActionProc actionProc) { // yielding procedure already transformed to atomic action var refinedAction = actionProc.RefinedActionAtLayer(layerNum); if (refinedAction == null) { // TODO: This can only happen because YieldingProcChecker.AddCheckers calls // VisitProcedure on every layer. Do this "call redirection" somewhere else? return(node); } return(refinedAction.proc); } else if (yieldingProc is SkipProc) { // calls to skip procedures are erased return(node); } else if (yieldingProc is MoverProc) { // mover procedure does not exist on this layer any more return(node); } } Procedure proc = (Procedure)node.Clone(); proc.Name = $"{node.Name}_{layerNum}"; proc.InParams = this.VisitVariableSeq(node.InParams); proc.OutParams = this.VisitVariableSeq(node.OutParams); proc.Requires = this.VisitRequiresSeq(node.Requires); proc.Ensures = this.VisitEnsuresSeq(node.Ensures); if (yieldingProc is MoverProc moverProc && yieldingProc.upperLayer == layerNum) { proc.Modifies = moverProc.modifiedGlobalVars.Select(g => Expr.Ident(g)).ToList(); } else { proc.Modifies = civlTypeChecker.sharedVariableIdentifiers; yieldingProcs.Add(proc); } procMap[node] = proc; }
private string CallCmdLabelAsync(CallCmd callCmd) { if (civlTypeChecker.procToIntroductionAction.ContainsKey(callCmd.Proc) || civlTypeChecker.procToLemmaProc.ContainsKey(callCmd.Proc)) { return(P); } if (civlTypeChecker.procToYieldInvariant.ContainsKey(callCmd.Proc)) { return(civlTypeChecker.procToYieldInvariant[callCmd.Proc].LayerNum == currLayerNum ? Y : P); } YieldingProc callee = civlTypeChecker.procToYieldingProc[callCmd.Proc]; if (callCmd.IsAsync) { if (callee is MoverProc && callee.upperLayer == currLayerNum) { return(ModifiesGlobalLabel(callee.proc.Modifies)); } if (callee is ActionProc actionProc && callee.upperLayer < currLayerNum) { if (callCmd.HasAttribute(CivlAttributes.SYNC)) { return(ModifiesGlobalLabel(actionProc.RefinedActionAtLayer(currLayerNum).modifiedGlobalVars)); } else { return(P); } } return(A); } else { if (callee is MoverProc && callee.upperLayer == currLayerNum) { return(ModifiesGlobalLabel(callee.proc.Modifies)); } if (callee is ActionProc actionProc && callee.upperLayer < currLayerNum) { return(ModifiesGlobalLabel(actionProc.RefinedActionAtLayer(currLayerNum).modifiedGlobalVars)); } return(Y); } }
public SkipRefinementInstrumentation( CivlTypeChecker civlTypeChecker, YieldingProc yieldingProc, Dictionary <Variable, Variable> oldGlobalMap) { this.oldGlobalMap = new Dictionary <Variable, Variable>(); foreach (Variable v in civlTypeChecker.sharedVariables) { var layerRange = civlTypeChecker.GlobalVariableLayerRange(v); if (layerRange.lowerLayerNum <= yieldingProc.upperLayer && yieldingProc.upperLayer < layerRange.upperLayerNum) { this.oldGlobalMap[v] = oldGlobalMap[v]; } } }
private void TransformImpl(Implementation impl) { HashSet <Block> yieldingLoopHeaders; Graph <Block> graph = ComputeYieldingLoopHeaders(impl, out yieldingLoopHeaders); // initialize globalSnapshotInstrumentation globalSnapshotInstrumentation = new GlobalSnapshotInstrumentation(civlTypeChecker); // initialize refinementInstrumentation Procedure originalProc = implMap[impl].Proc; YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[originalProc]; if (yieldingProc.upperLayer == this.layerNum) { refinementInstrumentation = new SomeRefinementInstrumentation( civlTypeChecker, impl, originalProc, globalSnapshotInstrumentation.OldGlobalMap, yieldingLoopHeaders); } else { refinementInstrumentation = new NoneRefinementInstrumentation(); } // initialize noninterferenceInstrumentation if (CommandLineOptions.Clo.TrustNonInterference) { noninterferenceInstrumentation = new NoneNoninterferenceInstrumentation(); } else { noninterferenceInstrumentation = new SomeNoninterferenceInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap, globalSnapshotInstrumentation.OldGlobalMap, yieldProc); } DesugarConcurrency(impl, graph, yieldingLoopHeaders); impl.LocVars.AddRange(globalSnapshotInstrumentation.NewLocalVars); impl.LocVars.AddRange(refinementInstrumentation.NewLocalVars); impl.LocVars.AddRange(noninterferenceInstrumentation.NewLocalVars); }
private int ParCallCmdLabel(ParCallCmd parCallCmd) { foreach (CallCmd callCmd in parCallCmd.CallCmds) { if (@base.civlTypeChecker.procToYieldingProc[callCmd.Proc].upperLayer >= currLayerNum) { return(Y); } } bool isRightMover = true; bool isLeftMover = true; int numAtomicActions = 0; foreach (CallCmd callCmd in parCallCmd.CallCmds) { YieldingProc callee = @base.civlTypeChecker.procToYieldingProc[callCmd.Proc]; isRightMover = isRightMover && callee.IsRightMover; isLeftMover = isLeftMover && callee.IsLeftMover; if (callee is ActionProc) { numAtomicActions++; } } if (isLeftMover && isRightMover) { return(B); } else if (isLeftMover) { return(L); } else if (isRightMover) { return(R); } Debug.Assert(numAtomicActions == 1); return(A); }
public SomeRefinementInstrumentation( CivlTypeChecker civlTypeChecker, Implementation impl, Implementation originalImpl, Dictionary <Variable, Variable> oldGlobalMap, HashSet <Block> yieldingLoopHeaders) { newLocalVars = new List <Variable>(); YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[originalImpl.Proc]; int layerNum = yieldingProc.upperLayer; pc = Pc(); newLocalVars.Add(pc); ok = Ok(); newLocalVars.Add(ok); this.transitionRelationCache = new Dictionary <AtomicAction, Expr>(); this.oldGlobalMap = new Dictionary <Variable, Variable>(); foreach (Variable v in civlTypeChecker.sharedVariables) { var layerRange = civlTypeChecker.GlobalVariableLayerRange(v); if (layerRange.lowerLayerNum <= yieldingProc.upperLayer && yieldingProc.upperLayer < layerRange.upperLayerNum) { this.oldGlobalMap[v] = oldGlobalMap[v]; } } oldOutputMap = new Dictionary <Variable, Variable>(); foreach (Variable f in impl.OutParams) { LocalVariable copy = Old(f); newLocalVars.Add(copy); oldOutputMap[f] = copy; } Dictionary <Variable, Expr> foroldMap = new Dictionary <Variable, Expr>(); foreach (Variable g in civlTypeChecker.sharedVariables) { foroldMap[g] = Expr.Ident(oldGlobalMap[g]); } if (yieldingProc is ActionProc actionProc) { // The parameters of an atomic action come from the implementation that denotes the atomic action specification. // To use the transition relation computed below in the context of the yielding procedure of the refinement check, // we need to substitute the parameters. AtomicAction atomicAction = actionProc.refinedAction; Implementation atomicActionImpl = atomicAction.impl; Dictionary <Variable, Expr> alwaysMap = new Dictionary <Variable, Expr>(); for (int i = 0; i < impl.InParams.Count; i++) { alwaysMap[atomicActionImpl.InParams[i]] = Expr.Ident(impl.InParams[i]); } for (int i = 0; i < impl.OutParams.Count; i++) { alwaysMap[atomicActionImpl.OutParams[i]] = Expr.Ident(impl.OutParams[i]); } if (atomicAction.HasPendingAsyncs) { Variable collectedPAs = civlTypeChecker.implToPendingAsyncCollector[originalImpl]; alwaysMap[atomicActionImpl.OutParams.Last()] = Expr.Ident(collectedPAs); LocalVariable copy = Old(collectedPAs); newLocalVars.Add(copy); oldOutputMap[collectedPAs] = copy; } Substitution always = Substituter.SubstitutionFromHashtable(alwaysMap); Substitution forold = Substituter.SubstitutionFromHashtable(foroldMap); Expr betaExpr = GetTransitionRelation(atomicAction); beta = Substituter.ApplyReplacingOldExprs(always, forold, betaExpr); Expr alphaExpr = Expr.And(atomicAction.gate.Select(g => g.Expr)); alphaExpr.Type = Type.Bool; alpha = Substituter.Apply(always, alphaExpr); } else { beta = Expr.And(this.oldGlobalMap.Keys.Select(v => Expr.Eq(Expr.Ident(v), foroldMap[v]))); alpha = Expr.True; } pcsForYieldingLoopsHeaders = new Dictionary <Block, Variable>(); oksForYieldingLoopHeaders = new Dictionary <Block, Variable>(); foreach (Block header in yieldingLoopHeaders) { var pcForYieldingLoopHeader = PcForYieldingLoopHeader(header); newLocalVars.Add(pcForYieldingLoopHeader); pcsForYieldingLoopsHeaders[header] = pcForYieldingLoopHeader; var okForYieldingLoopHeader = OkForYieldingLoopHeader(header); newLocalVars.Add(okForYieldingLoopHeader); oksForYieldingLoopHeaders[header] = okForYieldingLoopHeader; } }