Exemple #1
0
        /*
         * PerformYieldTypeChecking :
         * 3.1 Input parameters :
         * 3.1.1 MoverTypeChecker moverTypeChecker :
         * 3.2 Action : This function is called in TypeCheck.cs. This is the only function that is externalized. This function traverses the program declarations and performs
         */
        public static void PerformYieldTypeChecking(MoverTypeChecker moverTypeChecker)
        {
            Program          yieldTypeCheckedProgram = moverTypeChecker.program;
            YieldTypeChecker regExprToAuto           = new YieldTypeChecker();

            foreach (var decl in yieldTypeCheckedProgram.TopLevelDeclarations)
            {
                Implementation impl = decl as Implementation;
                if (impl == null)
                {
                    continue;
                }
                int phaseNumSpecImpl = moverTypeChecker.FindPhaseNumber(impl.Proc);

                YieldTypeCheckerCore     yieldTypeCheckerPerImpl = new YieldTypeCheckerCore(moverTypeChecker);
                List <Tuple <int, int> > phaseIntervals          = ComputePhaseIntervals(impl, phaseNumSpecImpl, moverTypeChecker); // Compute intervals

                for (int i = 0; i < phaseIntervals.Count; i++)                                                                      // take current phase check num from each interval
                {
                    int yTypeCheckCurrentPhaseNum = phaseIntervals[i].Item1;
                    Automaton <BvSet> yieldTypeCheckAutoPerPhase = yieldTypeCheckerPerImpl.YieldTypeCheckAutomaton(impl, phaseNumSpecImpl, yTypeCheckCurrentPhaseNum);
                    if (!IsYieldTypeSafe(yieldTypeCheckAutoPerPhase, impl, moverTypeChecker, i))
                    {
                        moverTypeChecker.Error(impl, "\n Body of " + impl.Proc.Name + " is not yield type safe " + "\n");
                    }
                }
            }
        }
Exemple #2
0
 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> >();
 }
Exemple #3
0
 public static void PerformYieldSafeCheck(MoverTypeChecker moverTypeChecker)
 {
     foreach (var impl in moverTypeChecker.program.Implementations)
     {
         if (!moverTypeChecker.procToActionInfo.ContainsKey(impl.Proc))
         {
             continue;
         }
         impl.PruneUnreachableBlocks();
         Graph <Block> implGraph = Program.GraphFromImpl(impl);
         implGraph.ComputeLoops();
         int specLayerNum = moverTypeChecker.procToActionInfo[impl.Proc].createdAtLayerNum;
         foreach (int layerNum in moverTypeChecker.AllCreatedLayerNums.Except(new int[] { moverTypeChecker.leastUnimplementedLayerNum }))
         {
             if (layerNum > specLayerNum)
             {
                 continue;
             }
             YieldTypeChecker executor = new YieldTypeChecker(moverTypeChecker, impl, layerNum, implGraph.Headers);
         }
     }
 }
Exemple #4
0
 public static void PerformYieldSafeCheck(CivlTypeChecker civlTypeChecker)
 {
     foreach (var impl in civlTypeChecker.program.Implementations)
     {
         if (!civlTypeChecker.procToActionInfo.ContainsKey(impl.Proc))
         {
             continue;
         }
         impl.PruneUnreachableBlocks();
         Graph <Block> implGraph = Program.GraphFromImpl(impl);
         implGraph.ComputeLoops();
         int specLayerNum = civlTypeChecker.procToActionInfo[impl.Proc].createdAtLayerNum;
         foreach (int layerNum in civlTypeChecker.AllLayerNums)
         {
             if (layerNum > specLayerNum)
             {
                 continue;
             }
             YieldTypeChecker executor = new YieldTypeChecker(civlTypeChecker, impl, layerNum, implGraph.Headers);
         }
     }
 }
Exemple #5
0
        public void TypeCheck()
        {
            foreach (Declaration decl in program.TopLevelDeclarations)
            {
                Procedure proc = decl as Procedure;
                if (proc == null)
                {
                    continue;
                }
                foreach (Ensures e in proc.Ensures)
                {
                    int       phaseNum;
                    MoverType moverType = MoverCheck.GetMoverType(e, out phaseNum);
                    if (moverType == MoverType.Top)
                    {
                        continue;
                    }
                    CodeExpr codeExpr = e.Condition as CodeExpr;
                    if (codeExpr == null)
                    {
                        Error(e, "An atomic action must be a CodeExpr");
                        continue;
                    }
                    if (procToActionInfo.ContainsKey(proc))
                    {
                        Error(proc, "A procedure can have at most one atomic action");
                        continue;
                    }
                    procToActionInfo[proc] = new ActionInfo(proc, codeExpr, moverType, phaseNum);
                }
            }
            this.VisitProgram(program);
#if QED
            YieldTypeChecker.PerformYieldTypeChecking(this);
#endif
        }
 public static void PerformYieldSafeCheck(MoverTypeChecker moverTypeChecker)
 {
     foreach (var impl in moverTypeChecker.program.Implementations)
     {
         if (!moverTypeChecker.procToActionInfo.ContainsKey(impl.Proc)) continue;
         impl.PruneUnreachableBlocks();
         Graph<Block> implGraph = Program.GraphFromImpl(impl);
         implGraph.ComputeLoops();
         int specLayerNum = moverTypeChecker.procToActionInfo[impl.Proc].createdAtLayerNum;
         foreach (int layerNum in moverTypeChecker.AllCreatedLayerNums.Except(new int[] { moverTypeChecker.leastUnimplementedLayerNum }))
         {
             if (layerNum > specLayerNum) continue;
             YieldTypeChecker executor = new YieldTypeChecker(moverTypeChecker, impl, layerNum, implGraph.Headers);
         }
     }
 }
Exemple #7
0
        public void TypeCheck()
        {
            foreach (var proc in program.Procedures)
            {
                if (!QKeyValue.FindBoolAttribute(proc.Attributes, "yields"))
                {
                    continue;
                }

                int        createdAtLayerNum; // must be initialized by the following code, otherwise it is an error
                int        availableUptoLayerNum = int.MaxValue;
                List <int> attrs = FindLayers(proc.Attributes);
                if (attrs.Count == 1)
                {
                    createdAtLayerNum = attrs[0];
                }
                else if (attrs.Count == 2)
                {
                    createdAtLayerNum     = attrs[0];
                    availableUptoLayerNum = attrs[1];
                }
                else
                {
                    Error(proc, "Incorrect number of layers");
                    continue;
                }
                foreach (Ensures e in proc.Ensures)
                {
                    MoverType moverType = GetMoverType(e);
                    if (moverType == MoverType.Top)
                    {
                        continue;
                    }
                    CodeExpr codeExpr = e.Condition as CodeExpr;
                    if (codeExpr == null)
                    {
                        Error(e, "An atomic action must be a CodeExpr");
                        continue;
                    }
                    if (procToActionInfo.ContainsKey(proc))
                    {
                        Error(proc, "A procedure can have at most one atomic action");
                        continue;
                    }
                    if (availableUptoLayerNum <= createdAtLayerNum)
                    {
                        Error(proc, "Creation layer number must be less than the available upto layer number");
                        continue;
                    }

                    minLayerNum         = int.MaxValue;
                    maxLayerNum         = -1;
                    canAccessSharedVars = true;
                    enclosingProc       = proc;
                    enclosingImpl       = null;
                    base.VisitEnsures(e);
                    canAccessSharedVars = false;
                    if (maxLayerNum > createdAtLayerNum)
                    {
                        Error(e, "A variable being accessed is introduced after this action is created");
                    }
                    else if (availableUptoLayerNum > minLayerNum)
                    {
                        Error(e, "A variable being accessed is hidden before this action becomes unavailable");
                    }
                    else
                    {
                        procToActionInfo[proc] = new AtomicActionInfo(proc, e, moverType, createdAtLayerNum, availableUptoLayerNum);
                    }
                }
                if (errorCount > 0)
                {
                    continue;
                }
                if (!procToActionInfo.ContainsKey(proc))
                {
                    if (availableUptoLayerNum < createdAtLayerNum)
                    {
                        Error(proc, "Creation layer number must be no more than the available upto layer number");
                        continue;
                    }
                    else
                    {
                        procToActionInfo[proc] = new ActionInfo(proc, createdAtLayerNum, availableUptoLayerNum);
                    }
                }
            }
            if (errorCount > 0)
            {
                return;
            }
            foreach (var impl in program.Implementations)
            {
                if (!procToActionInfo.ContainsKey(impl.Proc))
                {
                    continue;
                }
                procToActionInfo[impl.Proc].hasImplementation = true;
            }
            foreach (var proc in procToActionInfo.Keys)
            {
                ActionInfo actionInfo = procToActionInfo[proc];
                if (actionInfo.isExtern && actionInfo.hasImplementation)
                {
                    Error(proc, "Extern procedure cannot have an implementation");
                    continue;
                }
                if (actionInfo.isExtern || actionInfo.hasImplementation)
                {
                    continue;
                }
                if (leastUnimplementedLayerNum == int.MaxValue)
                {
                    leastUnimplementedLayerNum = actionInfo.createdAtLayerNum;
                }
                else if (leastUnimplementedLayerNum != actionInfo.createdAtLayerNum)
                {
                    Error(proc, "All unimplemented atomic actions must be created at the same layer");
                }
            }
            foreach (var g in this.globalVarToSharedVarInfo.Keys)
            {
                var info = globalVarToSharedVarInfo[g];
                if (!this.AllCreatedLayerNums.Contains(info.introLayerNum))
                {
                    Error(g, "Variable must be introduced with creation of some atomic action");
                }
                if (info.hideLayerNum != int.MaxValue && !this.AllCreatedLayerNums.Contains(info.hideLayerNum))
                {
                    Error(g, "Variable must be hidden with creation of some atomic action");
                }
            }
            if (errorCount > 0)
            {
                return;
            }
            this.VisitProgram(program);
            foreach (Procedure proc in program.Procedures)
            {
                if (procToActionInfo.ContainsKey(proc))
                {
                    continue;
                }
                foreach (var ie in proc.Modifies)
                {
                    if (!SharedVariables.Contains(ie.Decl))
                    {
                        continue;
                    }
                    Error(proc, "A ghost procedure must not modify a global variable with layer annotation");
                }
            }
            if (errorCount > 0)
            {
                return;
            }
            YieldTypeChecker.PerformYieldSafeCheck(this);
            new LayerEraser().VisitProgram(program);
        }
        /*
PerformYieldTypeChecking : 
 3.1 Input parameters :
   3.1.1 MoverTypeChecker moverTypeChecker : 
 3.2 Action : This function is called in TypeCheck.cs. This is the only function that is externalized. This function traverses the program declarations and performs
        */
        public static void PerformYieldTypeChecking(MoverTypeChecker moverTypeChecker)
        {
            Program yieldTypeCheckedProgram = moverTypeChecker.program;
            YieldTypeChecker regExprToAuto = new YieldTypeChecker();
            foreach (var decl in yieldTypeCheckedProgram.TopLevelDeclarations)
            {
                Implementation impl = decl as Implementation;
                if (impl == null) continue;
                int phaseNumSpecImpl = moverTypeChecker.FindPhaseNumber(impl.Proc);

                YieldTypeCheckerCore yieldTypeCheckerPerImpl = new YieldTypeCheckerCore(moverTypeChecker);
                List<Tuple<int, int>> phaseIntervals = ComputePhaseIntervals(impl, phaseNumSpecImpl, moverTypeChecker); // Compute intervals

                for (int i = 0; i < phaseIntervals.Count; i++) // take current phase check num from each interval
                {
                    int yTypeCheckCurrentPhaseNum = phaseIntervals[i].Item1;
                    Automaton<BvSet> yieldTypeCheckAutoPerPhase = yieldTypeCheckerPerImpl.YieldTypeCheckAutomaton(impl, phaseNumSpecImpl, yTypeCheckCurrentPhaseNum);
                    if (!IsYieldTypeSafe(yieldTypeCheckAutoPerPhase, impl, moverTypeChecker, i))
                    {
                        moverTypeChecker.Error(impl, "\n Body of " + impl.Proc.Name + " is not yield type safe " + "\n");
                    }
                }
            }
        }
        public void TypeCheck()
        {
            foreach (var proc in program.Procedures)
            {
                if (!QKeyValue.FindBoolAttribute(proc.Attributes, "pure"))
                {
                    continue;
                }
                if (QKeyValue.FindBoolAttribute(proc.Attributes, "yields"))
                {
                    Error(proc, "Pure procedure must not yield");
                    continue;
                }
                if (QKeyValue.FindBoolAttribute(proc.Attributes, "layer"))
                {
                    Error(proc, "Pure procedure must not have layers");
                    continue;
                }
                if (proc.Modifies.Count > 0)
                {
                    Error(proc, "Pure procedure must not modify a global variable");
                    continue;
                }
                procToAtomicProcedureInfo[proc] = new AtomicProcedureInfo();
            }
            foreach (var proc in program.Procedures)
            {
                if (QKeyValue.FindBoolAttribute(proc.Attributes, "yields"))
                {
                    continue;
                }
                var procLayerNums = FindLayers(proc.Attributes);
                if (procLayerNums.Count == 0)
                {
                    continue;
                }
                foreach (IdentifierExpr ie in proc.Modifies)
                {
                    if (!globalVarToSharedVarInfo.ContainsKey(ie.Decl))
                    {
                        Error(proc, "Atomic procedure cannot modify a global variable without layer numbers");
                        continue;
                    }
                }
                int lower, upper;
                if (procLayerNums.Count == 1)
                {
                    lower = procLayerNums[0];
                    upper = procLayerNums[0];
                }
                else if (procLayerNums.Count == 2)
                {
                    lower = procLayerNums[0];
                    upper = procLayerNums[1];
                    if (lower >= upper)
                    {
                        Error(proc, "Lower layer must be less than upper layer");
                        continue;
                    }
                }
                else
                {
                    Error(proc, "Atomic procedure must specify a layer range");
                    continue;
                }
                LayerRange layerRange = new LayerRange(lower, upper);
                procToAtomicProcedureInfo[proc] = new AtomicProcedureInfo(layerRange);
            }
            if (errorCount > 0)
            {
                return;
            }

            foreach (Implementation impl in program.Implementations)
            {
                if (!procToAtomicProcedureInfo.ContainsKey(impl.Proc))
                {
                    continue;
                }
                var atomicProcedureInfo = procToAtomicProcedureInfo[impl.Proc];
                if (atomicProcedureInfo.isPure)
                {
                    this.enclosingImpl = impl;
                    (new PurityChecker(this)).VisitImplementation(impl);
                }
                else
                {
                    this.enclosingImpl      = impl;
                    this.sharedVarsAccessed = new HashSet <Variable>();
                    (new PurityChecker(this)).VisitImplementation(impl);
                    LayerRange upperBound = FindLayerRange();
                    LayerRange lowerBound = atomicProcedureInfo.layerRange;
                    if (!lowerBound.Subset(upperBound))
                    {
                        Error(impl, "Atomic procedure cannot access global variable");
                    }
                    this.sharedVarsAccessed = null;
                }
            }
            if (errorCount > 0)
            {
                return;
            }

            foreach (var proc in program.Procedures)
            {
                if (!QKeyValue.FindBoolAttribute(proc.Attributes, "yields"))
                {
                    continue;
                }

                int        createdAtLayerNum; // must be initialized by the following code, otherwise it is an error
                int        availableUptoLayerNum = int.MaxValue;
                List <int> attrs = FindLayers(proc.Attributes);
                if (attrs.Count == 1)
                {
                    createdAtLayerNum = attrs[0];
                }
                else if (attrs.Count == 2)
                {
                    createdAtLayerNum     = attrs[0];
                    availableUptoLayerNum = attrs[1];
                }
                else
                {
                    Error(proc, "Incorrect number of layers");
                    continue;
                }
                foreach (Ensures e in proc.Ensures)
                {
                    MoverType moverType = GetMoverType(e);
                    if (moverType == MoverType.Top)
                    {
                        continue;
                    }
                    CodeExpr codeExpr = e.Condition as CodeExpr;
                    if (codeExpr == null)
                    {
                        Error(e, "An atomic action must be a CodeExpr");
                        continue;
                    }
                    if (procToActionInfo.ContainsKey(proc))
                    {
                        Error(proc, "A procedure can have at most one atomic action");
                        continue;
                    }
                    if (availableUptoLayerNum <= createdAtLayerNum)
                    {
                        Error(proc, "Creation layer number must be less than the available upto layer number");
                        continue;
                    }

                    sharedVarsAccessed = new HashSet <Variable>();
                    enclosingProc      = proc;
                    enclosingImpl      = null;
                    base.VisitEnsures(e);
                    LayerRange upperBound = FindLayerRange();
                    LayerRange lowerBound = new LayerRange(createdAtLayerNum, availableUptoLayerNum);
                    if (lowerBound.Subset(upperBound))
                    {
                        procToActionInfo[proc] = new AtomicActionInfo(proc, e, moverType, createdAtLayerNum, availableUptoLayerNum);
                    }
                    else
                    {
                        Error(e, "A variable being accessed in this action is unavailable");
                    }
                    sharedVarsAccessed = null;
                }
                if (errorCount > 0)
                {
                    continue;
                }
                if (!procToActionInfo.ContainsKey(proc))
                {
                    if (availableUptoLayerNum < createdAtLayerNum)
                    {
                        Error(proc, "Creation layer number must be no more than the available upto layer number");
                        continue;
                    }
                    else
                    {
                        procToActionInfo[proc] = new ActionInfo(proc, createdAtLayerNum, availableUptoLayerNum);
                    }
                }
            }
            if (errorCount > 0)
            {
                return;
            }

            foreach (var impl in program.Implementations)
            {
                if (!procToActionInfo.ContainsKey(impl.Proc))
                {
                    continue;
                }
                ActionInfo actionInfo = procToActionInfo[impl.Proc];
                procToActionInfo[impl.Proc].hasImplementation = true;
                if (actionInfo.isExtern)
                {
                    Error(impl.Proc, "Extern procedure cannot have an implementation");
                }
            }
            if (errorCount > 0)
            {
                return;
            }

            foreach (Procedure proc in procToActionInfo.Keys)
            {
                for (int i = 0; i < proc.InParams.Count; i++)
                {
                    Variable v     = proc.InParams[i];
                    var      layer = FindLocalVariableLayer(proc, v, procToActionInfo[proc].createdAtLayerNum);
                    if (layer == int.MinValue)
                    {
                        continue;
                    }
                    localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer);
                }
                for (int i = 0; i < proc.OutParams.Count; i++)
                {
                    Variable v     = proc.OutParams[i];
                    var      layer = FindLocalVariableLayer(proc, v, procToActionInfo[proc].createdAtLayerNum);
                    if (layer == int.MinValue)
                    {
                        continue;
                    }
                    localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer);
                }
            }
            foreach (Implementation node in program.Implementations)
            {
                if (!procToActionInfo.ContainsKey(node.Proc))
                {
                    continue;
                }
                foreach (Variable v in node.LocVars)
                {
                    var layer = FindLocalVariableLayer(node, v, procToActionInfo[node.Proc].createdAtLayerNum);
                    if (layer == int.MinValue)
                    {
                        continue;
                    }
                    localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer);
                }
                for (int i = 0; i < node.Proc.InParams.Count; i++)
                {
                    Variable v = node.Proc.InParams[i];
                    if (!localVarToLocalVariableInfo.ContainsKey(v))
                    {
                        continue;
                    }
                    var layer = localVarToLocalVariableInfo[v].layer;
                    localVarToLocalVariableInfo[node.InParams[i]] = new LocalVariableInfo(layer);
                }
                for (int i = 0; i < node.Proc.OutParams.Count; i++)
                {
                    Variable v = node.Proc.OutParams[i];
                    if (!localVarToLocalVariableInfo.ContainsKey(v))
                    {
                        continue;
                    }
                    var layer = localVarToLocalVariableInfo[v].layer;
                    localVarToLocalVariableInfo[node.OutParams[i]] = new LocalVariableInfo(layer);
                }
            }
            if (errorCount > 0)
            {
                return;
            }

            this.VisitProgram(program);
            if (errorCount > 0)
            {
                return;
            }
            YieldTypeChecker.PerformYieldSafeCheck(this);
            new LayerEraser().VisitProgram(program);
        }
Exemple #10
0
 public static void PerformYieldSafeCheck(CivlTypeChecker civlTypeChecker)
 {
     foreach (var impl in civlTypeChecker.program.Implementations)
     {
         if (!civlTypeChecker.procToActionInfo.ContainsKey(impl.Proc)) continue;
         impl.PruneUnreachableBlocks();
         Graph<Block> implGraph = Program.GraphFromImpl(impl);
         implGraph.ComputeLoops();
         int specLayerNum = civlTypeChecker.procToActionInfo[impl.Proc].createdAtLayerNum;
         foreach (int layerNum in civlTypeChecker.AllImplementedLayerNums)
         {
             if (layerNum > specLayerNum) continue;
             YieldTypeChecker executor = new YieldTypeChecker(civlTypeChecker, impl, layerNum, implGraph.Headers);
         }
     }
 }