예제 #1
0
        public async Task <byte[]> LoadBytesFromPath(RelativePath path)
        {
            var fullPath = ExtractedModlistFolder !.Dir.Combine(path);

            if (!fullPath.IsFile)
            {
                throw new Exception($"Cannot load inlined data {path} file does not exist");
            }

            return(await fullPath.ReadAllBytesAsync());
        }
예제 #2
0
    public static bool RunTest(string toolchainName, Compiler compile, Exe runner, File source)
    {
        var destPath   = tests_results.Combine(source);
        var sourcePath = tests.Combine(source);
        var expected   = sourcePath.DropExtension().Combine(Ext(".o"));

        Console.Write($"\x1b[KRunning test {source} ({toolchainName}) ");

        destPath.DirName().Create();

        UserErrorException exception = null;

        try {
            CompileToFile(compile, sourcePath, destPath);
        } catch (UserErrorException e) {
            exception = e;
        }

        if (exception != null)
        {
            Console.WriteLine("");
            Console.WriteLine("\x1b[1;31mFail\x1b[m");
            Console.WriteLine($"\x1b[1;33m{exception.Message}\x1b[m\n");
            return(false);
        }
        else
        {
            var actualStr   = runner.Run(destPath);
            var expectedStr = expected.Read();
            if (actualStr != expectedStr)
            {
                Console.WriteLine("\x1b[1;31mFail\x1b[m");
                Console.WriteLine($"\x1b[1;33m{source}: expected {expectedStr} but got {actualStr}.\x1b[m\n");
                return(false);
            }
            else
            {
                Console.Write("\x1b[1;32mOK\x1b[m\n"); // \r at the end for quiet
                return(true);
            }
        }
    }
예제 #3
0
        /// <summary>
        /// Executes the actual algorithm.
        /// </summary>
        protected override void DoRun()
        {
            float  distance;
            ushort edgeProfile;

            var enumerator1 = _source.GetEdgeEnumerator();
            var enumerator2 = _source.GetEdgeEnumerator();

            for (uint v = 0; v < _source.VertexCount; v++)
            {
                enumerator1.MoveTo(v);
                while (enumerator1.MoveNext())
                {
                    EdgeDataSerializer.Deserialize(enumerator1.Data0,
                                                   out distance, out edgeProfile);
                    var accessible1 = false;
                    var weight1     = _weightHandler.CalculateWeightAndDir(edgeProfile, distance, out accessible1);
                    if (enumerator1.DataInverted)
                    {
                        var dir = weight1.Direction;
                        dir.Reverse();
                        weight1.Direction = dir;
                    }
                    if (!accessible1)
                    { // not accessible.
                        continue;
                    }
                    var direction1 = weight1.Direction;
                    var edge1      = enumerator1.DirectedEdgeId();

                    // look at the neighbours of this edge.
                    enumerator2.MoveTo(enumerator1.To);
                    _restrictions.Update(enumerator1.To);
                    while (enumerator2.MoveNext())
                    {
                        var turn = new Turn(new OriginalEdge(v, enumerator1.To), Constants.NO_VERTEX);
                        EdgeDataSerializer.Deserialize(enumerator2.Data0,
                                                       out distance, out edgeProfile);
                        var accessible2 = false;
                        var weight2     = _weightHandler.CalculateWeightAndDir(edgeProfile, distance, out accessible2);
                        if (enumerator2.DataInverted)
                        {
                            var dir = weight2.Direction;
                            dir.Reverse();
                            weight2.Direction = dir;
                        }
                        if (!accessible2)
                        { // not accessible.
                            continue;
                        }

                        var direction2 = weight2.Direction;
                        turn.Vertex3 = enumerator2.To;
                        if (turn.IsUTurn)
                        { // is a u-turn, leave this out!
                            continue;
                        }

                        var direction = Dir.Combine(direction1, direction2);

                        if (direction.F &&
                            turn.IsRestrictedBy(_restrictions))
                        { // turn is restricted.
                            direction.F = false;
                        }

                        if (!direction.F)
                        { // there is no possible combination for these two edges.
                            continue;
                        }

                        // ok, we need to add this edge, it's a non-restricted turn, not a u-turn and edges are in correct direction.
                        var edge2 = enumerator2.DirectedEdgeId();

                        _weightHandler.AddOrUpdateEdge(_target, edge1.Raw, edge2.Raw, Constants.NO_VERTEX, true,
                                                       weight1.Weight);
                        //direction.Reverse();
                        _weightHandler.AddOrUpdateEdge(_target, edge2.Raw, edge1.Raw, Constants.NO_VERTEX, false,
                                                       weight1.Weight);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Calculates witness paths.
        /// </summary>
        public virtual void Calculate(DirectedGraph graph, WeightHandler <T> weightHandler, uint vertex,
                                      uint source, Dictionary <uint, Shortcut <T> > targets, int maxSettles, int hopLimit)
        {
            pathTree.Clear();
            pointerHeap.Clear();

            var forwardSettled  = new HashSet <uint>();
            var backwardSettled = new HashSet <uint>();

            var forwardTargets  = new HashSet <uint>();
            var backwardTargets = new HashSet <uint>();

            var maxWeight = 0f;

            foreach (var targetPair in targets)
            {
                var target   = targetPair.Key;
                var shortcut = targetPair.Value;
                var e        = new OriginalEdge(source, target);

                var shortcutForward = weightHandler.GetMetric(shortcut.Forward);
                if (shortcutForward > 0 && shortcutForward < float.MaxValue)
                {
                    forwardTargets.Add(e.Vertex2);
                    if (shortcutForward > maxWeight)
                    {
                        maxWeight = shortcutForward;
                    }
                }
                var shortcutBackward = weightHandler.GetMetric(shortcut.Backward);
                if (shortcutBackward > 0 && shortcutBackward < float.MaxValue)
                {
                    backwardTargets.Add(e.Vertex2);
                    if (shortcutBackward > maxWeight)
                    {
                        maxWeight = shortcutBackward;
                    }
                }
            }

            // queue the source.
            pathTree.Clear();
            pointerHeap.Clear();
            var p = pathTree.AddSettledVertex(source, new WeightAndDir <float>()
            {
                Direction = new Dir(true, true),
                Weight    = 0
            }, 0);

            pointerHeap.Push(p, 0);

            // dequeue vertices until stopping conditions are reached.
            var cVertex = Constants.NO_VERTEX;
            WeightAndDir <float> cWeight;
            var cHops      = uint.MaxValue;
            var enumerator = graph.GetEdgeEnumerator();

            while (pointerHeap.Count > 0)
            {
                var cPointer = pointerHeap.Pop();
                pathTree.GetSettledVertex(cPointer, out cVertex, out cWeight, out cHops);

                if (cVertex == vertex)
                {
                    continue;
                }

                if (cWeight.Weight >= maxWeight)
                {
                    break;
                }

                if (forwardSettled.Contains(cVertex) ||
                    forwardTargets.Count == 0 ||
                    forwardSettled.Count > maxSettles)
                {
                    cWeight.Direction = new Dir(false, cWeight.Direction.B);
                }
                if (backwardSettled.Contains(cVertex) ||
                    backwardTargets.Count == 0 ||
                    backwardSettled.Count > maxSettles)
                {
                    cWeight.Direction = new Dir(cWeight.Direction.F, false);
                }

                if (cWeight.Direction.F)
                {
                    forwardSettled.Add(cVertex);
                    if (forwardTargets.Contains(cVertex))
                    { // target reached, evaluate it as a shortcut.
                        Shortcut <T> shortcut;
                        if (targets.TryGetValue(cVertex, out shortcut))
                        {
                            var shortcutForward = weightHandler.GetMetric(shortcut.Forward);
                            if (shortcutForward > cWeight.Weight)
                            { // a witness path was found, don't add a shortcut.
                                shortcut.Forward = weightHandler.Zero;
                                targets[cVertex] = shortcut;
                            }
                        }
                        forwardTargets.Remove(cVertex);
                        if (forwardTargets.Count == 0)
                        {
                            if (backwardTargets.Count == 0)
                            {
                                break;
                            }
                            cWeight.Direction = new Dir(false, cWeight.Direction.B);
                            if (!cWeight.Direction.F && !cWeight.Direction.B)
                            {
                                continue;
                            }
                        }
                    }
                }
                if (cWeight.Direction.B)
                {
                    backwardSettled.Add(cVertex);
                    if (backwardTargets.Contains(cVertex))
                    { // target reached, evaluate it as a shortcut.
                        Shortcut <T> shortcut;
                        if (targets.TryGetValue(cVertex, out shortcut))
                        {
                            var shortcutBackward = weightHandler.GetMetric(shortcut.Backward);
                            if (shortcutBackward > cWeight.Weight)
                            { // a witness path was found, don't add a shortcut.
                                shortcut.Backward = weightHandler.Zero;
                                targets[cVertex]  = shortcut;
                            }
                        }
                        backwardTargets.Remove(cVertex);
                        if (backwardTargets.Count == 0)
                        {
                            if (forwardTargets.Count == 0)
                            {
                                break;
                            }
                            cWeight.Direction = new Dir(cWeight.Direction.F, false);
                            if (!cWeight.Direction.F && !cWeight.Direction.B)
                            {
                                continue;
                            }
                        }
                    }
                }

                if (cHops + 1 >= hopLimit)
                {
                    continue;
                }

                if (forwardSettled.Count > maxSettles &&
                    backwardSettled.Count > maxSettles)
                {
                    continue;
                }

                enumerator.MoveTo(cVertex);
                while (enumerator.MoveNext())
                {
                    var nVertex = enumerator.Neighbour;
                    var nWeight = ContractedEdgeDataSerializer.Deserialize(enumerator.Data0);

                    nWeight = new WeightAndDir <float>()
                    {
                        Direction = Dir.Combine(cWeight.Direction, nWeight.Direction),
                        Weight    = cWeight.Weight + nWeight.Weight
                    };

                    if (nWeight.Direction.F &&
                        forwardSettled.Contains(nVertex))
                    {
                        nWeight.Direction = new Dir(false, nWeight.Direction.B);
                    }
                    if (nWeight.Direction.B &&
                        backwardSettled.Contains(nVertex))
                    {
                        nWeight.Direction = new Dir(nWeight.Direction.F, false);
                    }
                    if (!nWeight.Direction.F && !nWeight.Direction.B)
                    {
                        continue;
                    }

                    var nPoiner = pathTree.AddSettledVertex(nVertex, nWeight, cHops + 1);
                    pointerHeap.Push(nPoiner, nWeight.Weight);
                }
            }
        }