예제 #1
0
 public Dictionary <AtomicPath, AtomicPath> CreatePathMap(AtomicSpec hAtomic,
                                                          Dictionary <NextRoutine, NextRoutine> nextRoutineMap,
                                                          bool avoidFinalUnmappedStoppingStep = true)
 {
     return(atomicPaths.Where(p => p.Mappable(nextRoutineMap, p.Stopping, avoidFinalUnmappedStoppingStep)).ToDictionary(
                lPath => lPath,
                lPath => lPath.Tau ? hAtomic.TauPath
                           : hAtomic.FindAtomicPathByNextRoutines(lPath.MapNextRoutines(nextRoutineMap))));
 }
예제 #2
0
 public AtomicPathPrefix(AtomicSpec i_atomicSpec, ArmadaPC pc)
 {
     atomicSpec   = i_atomicSpec;
     nextRoutines = new List <NextRoutine>();
     tau          = false;
     startPC      = endPC = pc;
     startType    = endType = atomicSpec.GetPCAtomicType(pc);
     extensions   = new List <AtomicPathPrefix>();
     path         = null;
 }
예제 #3
0
 public ReductionPathPrinter(AtomicSpec i_atomicSpec, string i_uniq, string i_state, string i_nextState, string i_path, string i_tid)
     : base(i_atomicSpec)
 {
     State     = i_state;
     NextState = i_nextState;
     Path      = i_path;
     Steps     = i_uniq + "_steps";
     States    = i_uniq + "_states";
     Tid       = i_tid;
 }
예제 #4
0
        public PrefixedVarsPathPrinter(AtomicSpec i_atomicSpec) : base(i_atomicSpec)
        {
            var prefix = atomicSpec.Low ? "l" : "h";

            State     = prefix + State;
            NextState = prefix + NextState;
            States    = prefix + States;
            Steps     = prefix + Steps;
            Path      = prefix + Path;
        }
예제 #5
0
 public PathPrinter(AtomicSpec i_atomicSpec)
 {
     state       = "s";
     nextState   = "s'";
     tid         = "tid";
     steps       = "steps";
     states      = "states";
     step        = "step";
     path        = "path";
     paramsParam = "params";
     atomicSpec  = i_atomicSpec;
 }
예제 #6
0
        public AtomicPathPrefix(AtomicSpec i_atomicSpec, List <NextRoutine> i_nextRoutines, bool i_tau, AtomicPathPrefix parent)
        {
            atomicSpec   = i_atomicSpec;
            nextRoutines = new List <NextRoutine>(i_nextRoutines);
            tau          = i_tau;
            startPC      = nextRoutines[0].startPC;
            endPC        = nextRoutines[nextRoutines.Count - 1].endPC;
            startType    = atomicSpec.GetPCAtomicType(startPC);
            endType      = nextRoutines[nextRoutines.Count - 1].Stopping ? PCAtomicType.Stopping : atomicSpec.GetPCAtomicType(endPC);
            extensions   = new List <AtomicPathPrefix>();
            path         = null;

            if (parent != null)
            {
                parent.AddExtension(this);
            }

            if (tau)
            {
                name = "Tau";
            }
            else
            {
                name  = UndefinedBehavior ? "UB_" : "";
                name += $"From_{startPC.methodName}_{startPC.Name}";

                // It's possible for two atomic paths to have the same start
                // and end PCs.  But, every path has to have a distinct name,
                // so we sometimes have to name a path with more than just the
                // start and end PCs.
                //
                // One way for two atomic paths with the same start and end
                // PCs to differ is via returning to different PCs.  For
                // instance, consider the following code:
                //
                //   method {:atomic} A {
                //     S1;
                //   label L:
                //     S2;
                //   }
                //
                //   method B {
                //     atomic {
                //       A();
                //       A();
                //       A();
                //     }
                //   }
                //
                // Here, there are two ways to get from label L to label L:
                // (1) by returning from B's first call to A and then making
                // B's second call to A, and (2) by returning from B's second
                // call to A and then making B's third call to A.  So, to make
                // sure such paths have different names, we include in the
                // name every returned-to PC in a step other than the last one
                // in the path.
                //
                // Another way for two atomic paths with the same start and
                // end PCs to differ is via branch outcomes.  For instance,
                // consider the following code:
                //
                //   atomic {
                //     if P {
                //       S1;
                //     }
                //     S2;
                //   }
                //
                // Here, there are two ways to get from the beginning to the
                // end: via the true branch of the if (passing through
                // statement S1) or via the false branch.  So we distinguish
                // the names of such paths by the branch outcomes.

                bool justBranched = false;
                for (var i = 0; i < nextRoutines.Count; ++i)
                {
                    var nextRoutine = nextRoutines[i];
                    if (i < nextRoutines.Count - 1 && nextRoutine.nextType == NextType.Return)
                    {
                        var returnToPC = nextRoutine.endPC;
                        name        += $"_Via_{returnToPC.methodName}_{returnToPC.Name}";
                        justBranched = false;
                    }

                    bool branchOutcome;
                    if (nextRoutine.TryGetBranchOutcome(out branchOutcome))
                    {
                        if (!justBranched)
                        {
                            name += "_";
                        }
                        name        += (branchOutcome ? "T" : "F");
                        justBranched = true;
                    }
                }

                if (endPC == null)
                {
                    name += "_to_exit";
                }
                else
                {
                    name += $"_To_{endPC.methodName}_{endPC.Name}";
                }
            }
        }
예제 #7
0
        ///////////////////////////////////////////////////////////////////////
        // PATH MAPPING
        ///////////////////////////////////////////////////////////////////////

        public Dictionary <AtomicPath, AtomicPath> CreatePathMap(AtomicSpec hAtomic)
        {
            return(atomicPaths.ToDictionary(
                       lPath => lPath,
                       lPath => lPath.Tau ? hAtomic.TauPath : hAtomic.FindAtomicPathByPCs(lPath.GetPCs(), lPath.Stopping)));
        }