コード例 #1
0
        private void VisitFunction(Function function)
        {
            Debug.Assert(function.OutParams.Count == 1);
            List <CommutativityHint> hints = new List <CommutativityHint>();

            // First we collect all {:commutativity "first_action", "second_action"} attributes
            for (QKeyValue kv = function.Attributes; kv != null; kv = kv.Next)
            {
                if (kv.Key != CivlAttributes.COMMUTATIVITY)
                {
                    continue;
                }
                if (kv.Params.Count == 2 &&
                    kv.Params[0] is string firstActionName &&
                    kv.Params[1] is string secondActionName)
                {
                    firstAction  = ctc.FindAtomicActionOrAbstraction(firstActionName);
                    secondAction = ctc.FindAtomicActionOrAbstraction(secondActionName);
                    if (firstAction == null)
                    {
                        ctc.Error(kv, $"Could not find atomic action {firstActionName}");
                    }
                    if (secondAction == null)
                    {
                        ctc.Error(kv, $"Could not find atomic action {secondActionName}");
                    }
                    if (firstAction != null && secondAction != null)
                    {
                        CheckInParams(function.InParams);
                    }
                    hints.Add(new CommutativityHint(function, firstAction, secondAction, args));
                }
コード例 #2
0
ファイル: Witnesses.cs プロジェクト: marcoeilers/boogie
 private void VisitFunction(Function function)
 {
     Debug.Assert(function.OutParams.Count == 1);
     for (QKeyValue kv = function.Attributes; kv != null; kv = kv.Next)
     {
         if (kv.Key != CivlAttributes.WITNESS)
         {
             continue;
         }
         if (kv.Params.Count == 3 &&
             kv.Params[0] is string witnessedVariableName &&
             kv.Params[1] is string firstActionName &&
             kv.Params[2] is string secondActionName)
         {
             witnessedVariable = ctc.sharedVariables.Find(v => v.Name == witnessedVariableName);
             if (witnessedVariable == null)
             {
                 ctc.Error(kv, $"Could not find shared variable {witnessedVariableName}");
             }
             else if (!function.OutParams[0].TypedIdent.Type.Equals(witnessedVariable.TypedIdent.Type))
             {
                 ctc.Error(function, "Result type does not match witnessed variable");
             }
             firstAction  = ctc.FindAtomicAction(firstActionName);
             secondAction = ctc.FindAtomicAction(secondActionName);
             if (firstAction == null)
             {
                 ctc.Error(kv, $"Could not find atomic action {firstActionName}");
             }
             if (secondAction == null)
             {
                 ctc.Error(kv, $"Could not find atomic action {firstActionName}");
             }
             if (firstAction != null && secondAction != null)
             {
                 CheckInParams(function.InParams);
             }
             allWitnessFunctions.Add(new WitnessFunction(function, witnessedVariable,
                                                         firstAction, secondAction, args));
         }
コード例 #3
0
            public override Cmd VisitCallCmd(CallCmd node)
            {
                Procedure enclosingProc = civlTypeChecker.enclosingImpl.Proc;

                if (!civlTypeChecker.procToAtomicProcedureInfo.ContainsKey(node.Proc))
                {
                    civlTypeChecker.Error(node, "Atomic procedure can only call an atomic procedure");
                    return(base.VisitCallCmd(node));
                }
                var callerInfo = civlTypeChecker.procToAtomicProcedureInfo[enclosingProc];
                var calleeInfo = civlTypeChecker.procToAtomicProcedureInfo[node.Proc];

                if (calleeInfo.isPure)
                {
                    // do nothing
                }
                else if (callerInfo.isPure)
                {
                    civlTypeChecker.Error(node, "Pure procedure can only call pure procedures");
                }
                else if (!callerInfo.layerRange.Subset(calleeInfo.layerRange))
                {
                    civlTypeChecker.Error(node, "Caller layers must be subset of callee layers");
                }
                return(base.VisitCallCmd(node));
            }
コード例 #4
0
            private void LoopCheck()
            {
                var graph = new Graph <Absy>(new HashSet <Tuple <Absy, Absy> >(atomicityLabels.Keys));

                graph.AddSource(initialState);
                graph.ComputeLoops();

                var edgeToLoopHeader = new Dictionary <Tuple <Absy, Absy>, Block>();

                foreach (Block header in graph.SortHeadersByDominance())
                {
                    foreach (var source in graph.BackEdgeNodes(header))
                    {
                        edgeToLoopHeader[new Tuple <Absy, Absy>(source, header)] = header;
                        foreach (var node in graph.NaturalLoops(header, source))
                        {
                            if (node == header)
                            {
                                continue;
                            }
                            foreach (var pred in graph.Predecessors(node))
                            {
                                var edge = new Tuple <Absy, Absy>(pred, node);
                                if (edgeToLoopHeader.ContainsKey(edge))
                                {
                                    continue;
                                }
                                edgeToLoopHeader[edge] = header;
                            }
                        }
                    }
                }

                var parentLoopHeader = new Dictionary <Block, Block>();

                foreach (Block header in graph.Headers)
                {
                    foreach (var pred in graph.Predecessors(header).Except(graph.BackEdgeNodes(header)))
                    {
                        var edge = new Tuple <Absy, Absy>(pred, header);
                        if (edgeToLoopHeader.ContainsKey(edge))
                        {
                            parentLoopHeader[header] = edgeToLoopHeader[edge];
                            break;
                        }
                    }
                }

                var yieldingLoopHeaders = new HashSet <Block>(graph.Headers.OfType <Block>()
                                                              .Where(header => civlTypeChecker.IsYieldingLoopHeader(header, currLayerNum)));

                foreach (var header in parentLoopHeader.Keys)
                {
                    var parentHeader = parentLoopHeader[header];
                    if (yieldingLoopHeaders.Contains(header) && !yieldingLoopHeaders.Contains(parentHeader))
                    {
                        civlTypeChecker.Error(parentHeader,
                                              $"Loop header must be yielding at layer {currLayerNum}");
                    }
                }

                foreach (var edge in edgeToLoopHeader.Keys)
                {
                    var header = edgeToLoopHeader[edge];
                    if (yieldingLoopHeaders.Contains(header))
                    {
                        continue;
                    }
                    if (atomicityLabels[edge] == Y)
                    {
                        civlTypeChecker.Error(header,
                                              $"Loop header must be yielding at layer {currLayerNum}");
                    }
                }
            }
コード例 #5
0
 private void Error(string msg)
 {
     ctc.Error(node, msg);
     errorCount++;
 }