예제 #1
0
        private FluentString GetPropReport(ISolver solver, SolverState commandState)
        {
            Report.WriteLine("Solver: {0}", SolverHelper.Describe(solver));

            var propsReport = new FluentString();

            propsReport.Append(solver.TypeDescriptor);
            try
            {
                var typeDescriptorProps = solver.GetTypeDescriptorProps(commandState);
                if (typeDescriptorProps != null)
                {
                    foreach (var(name, text) in typeDescriptorProps)
                    {
                        propsReport.AppendLine($"-> {name,20}: {text}");
                        Report.WriteLine($"-> {name,20}: {text}");
                    }
                }
            }
            catch (NotSupportedException)
            {
                var msg = $"Solver [{solver.GetType().Name}] does not support {typeof(IExtendedFunctionalityDescriptor).Name}";
                Report.WriteLine(msg);
                propsReport.AppendLine(msg);
            }
            catch (NotImplementedException)
            {
                var msg = $"Solver [{solver.GetType().Name}] does not support {typeof(IExtendedFunctionalityDescriptor).Name}";
                Report.WriteLine(msg);
                propsReport.AppendLine(msg);
            }

            return(propsReport);
        }
예제 #2
0
        public PlainUtils CreatePlainerType()
        {
            var cloned = new PlainUtils();

            cloned.FluentString = FluentString.CreatePlainerType();
            return(cloned);
        }
예제 #3
0
        public void RenderToGraphVis()
        {
            var sample = new int[] { 23, 5, 12, 55, 67, 34, 33 };

            var bst = new BinarySearchTree <int>(new IntComparer());

            foreach (var val in sample)
            {
                var n = bst.Add(val);
            }

            var sb = new FluentString();

            sb.AppendLine("digraph g {");
            sb.AppendLine("rankdir=TB;");
            foreach (var node in bst.GetNodes())
            {
                if (node.Left != null)
                {
                    sb.AppendLine($"\t{node.Value}->{node.Left.Value}[label=\"L\"]");
                }
                if (node.Right != null)
                {
                    sb.AppendLine($"\t{node.Value}->{node.Right.Value}[label=\"R\"]");
                }
                // if (node.Parent != null)  sb.AppendLine($"\t{node.Value}->{node.Parent.Value}");
            }

            sb.AppendLine("}");

            outp.WriteLine(sb);
        }
예제 #4
0
        /// <summary>
        /// dot .\Exhause.dot -o file.svg -T svg
        /// </summary>
        public void Render(IEnumerable <SolverNode> items, TextWriter tw)
        {
            var sb = FluentString.Create()
                     .AppendLine("digraph{ rankdir=BT;")
                     .ForEach(items, (fb, x) =>
            {
                string lbl = x.SolverNodeId.ToString();
                string bg  = null;
                var shape  = "";
                if (x.Parent == null)
                {
                    shape = "doublecircle";
                }
                else if (x.Status == SolverNodeStatus.Dead || x.Status == SolverNodeStatus.DeadRecursive)
                {
                    shape = "square";
                    bg    = "gray";
                }
                else if (x.Status == SolverNodeStatus.Solution)
                {
                    shape = "tripleoctagon";
                }
                else if (x.Status == SolverNodeStatus.SolutionPath)
                {
                    shape = "doubleoctagon";
                }
                else if (x.Status == SolverNodeStatus.Evaluted || x.Status == SolverNodeStatus.Evaluted)
                {
                    shape = "diamond";
                }
                else if (x.Status == SolverNodeStatus.Duplicate)
                {
                    shape = "tab";
                    if (x is ISolverNodeDuplicateLink dupLink)
                    {
                        lbl += "->" + dupLink.Duplicate?.SolverNodeId ?? "?";
                    }
                }
                else
                {
                    shape = "cylinder";
                }

                fb.Append($"{x.SolverNodeId} [label=\"{lbl}\" shape=\"{shape}\"");

                if (bg != null)
                {
                    fb.Append($" style=\"filled\", fillcolor=\"{bg}\"");
                }

                fb.AppendLine("]");
            })
                     .AppendLine("")
                     .ForEach(items.Where(x => x.Parent != null), (fb, x) => fb.AppendLine($"{x.SolverNodeId} -> {x.Parent?.SolverNodeId.ToString() ?? "null"}"))
                     .Append("}");

            tw.WriteLine(sb);
        }
예제 #5
0
파일: Scope.cs 프로젝트: Ygg01/Linguini
        /// <summary>
        /// Method that compares a Fluent string to a Fluent number
        /// </summary>
        /// <param name="scope">Scope of Fluent Bundle</param>
        /// <param name="fs1"></param>
        /// <param name="fn2"></param>
        /// <returns></returns>
        public static bool MatchByPluralCategory(this IScope scope, FluentString fs1, FluentNumber fn2)
        {
            if (!fs1.TryGetPluralCategory(out var strCategory))
            {
                return(false);
            }
            var numCategory = scope.GetPluralRules(RuleType.Cardinal, fn2);

            return(numCategory == strCategory);
        }
 internal static ILocValue ToLocValue(this IFluentType arg)
 {
     return(arg switch
     {
         FluentNone => new LocValueNone(""),
         FluentNumber number => new LocValueNumber(number),
         FluentString str => new LocValueString(str),
         FluentLocWrapperType value => value.WrappedValue,
         _ => throw new ArgumentOutOfRangeException(nameof(arg)),
     });
예제 #7
0
        public void TestFluentString()
        {
            var str = new FluentString("test string");
            var ctx = new MessageContext("en-US");

            str.Match(ctx, new FluentString("test string")).Should().BeTrue();
            str.Match(ctx, "fifty").Should().BeFalse();
            str.Match(ctx, "test string").Should().BeTrue();
            str.Match(ctx, 45).Should().BeFalse();
        }
예제 #8
0
        public static bool TryWrite(this IExpression expression, TextWriter writer, Scope scope)
        {
            var errors = new List <FluentError>();

            if (expression is IInlineExpression inlineExpression)
            {
                inlineExpression.Write(writer, scope);
            }
            else if (expression is SelectExpression selectExpression)
            {
                var selector = selectExpression.Selector.Resolve(scope);
                if (selector is FluentString or FluentNumber)
                {
                    foreach (var variant in selectExpression.Variants)
                    {
                        IFluentType key;
                        switch (variant.Type)
                        {
                        case VariantType.NumberLiteral:
                            key = FluentNumber.TryNumber(variant.Key.Span);
                            break;

                        default:
                            key = new FluentString(variant.Key.Span);
                            break;
                        }

                        if (key.Matches(selector, scope))
                        {
                            variant.Value.Write(writer, scope);
                            return(scope.Errors.Count == 0);
                        }
                    }
                }

                for (var i = 0; i < selectExpression.Variants.Count; i++)
                {
                    var variant = selectExpression.Variants[i];
                    if (variant.IsDefault)
                    {
                        variant.Value.Write(writer, scope);
                        return(errors.Count == 0);
                    }
                }

                errors.Add(ResolverFluentError.MissingDefault());
            }

            return(scope.Errors.Count == 0);
        }
        public ConsoleProgressNotifier(TextWriter tele)
            : base(TextWriter.Null) // we want a different format to go to file
        {
            this.tele = tele;

            var telText = new FluentString(",")
                          .Append("DurationInSec").Sep()
                          .Append("TotalNodes").Sep()
                          .Append("NodesPerSec").Sep()
                          .Append("NodesDelta").Sep()
                          .Append("MemoryUsed")
            ;

            tele.WriteLine(telText);
        }
예제 #10
0
        protected override string Render(ISolver caller, SolverState state, SolverStatistics global, string txt)
        {
            if (global == null)
            {
                return(null);
            }

            var totalMemory = System.GC.GetTotalMemory(false);

            var delta = (prev != null) ? global.TotalNodes - prev.TotalNodes : global.TotalNodes;

            var sb = new FluentString()
                     .Append(txt)
                     .Sep()
                     .Append($"delta:{delta:#,##0}")
                     .Sep()
                     .Append($"mem({Humanise.SizeSuffix((ulong) totalMemory)} used")
                     .Block(b =>
            {
                if (DevHelper.TryGetTotalMemory(out var avail))
                {
                    b.Sep();
                    b.Append($"{Humanise.SizeSuffix(avail)} avail");
                }
            })
                     .Append(")");


            var telText = new FluentString(",")
                          .Append(global.DurationInSec.ToString()).Sep()
                          .Append(global.TotalNodes.ToString()).Sep()
                          .Append(global.NodesPerSec.ToString()).Sep()
                          .Append(delta.ToString()).Sep()
                          .Append(totalMemory.ToString()).Sep()
            ;

            tele.WriteLine(telText);

            prev = new SolverStatistics(global);



            return(sb);
        }
예제 #11
0
        public string ToString(bool verbose, bool skipName = false)
        {
            var builder = new FluentString()
                          .If(Name != null && !skipName, $"{Name,-40}");

            if (DurationInSec <= 0d || TotalNodes <= 0)
            {
                return(builder.Append($"{TotalNodes,12:#,##0} nodes"));
            }

            builder.When(verbose, then =>
                         then.If(TotalDead >= 0, () => $" Dead={TotalDead:#,##0}:{TotalDead * 100 / TotalNodes:0}%")
                         .If(Duplicates >= 0, () => $" Dup={Duplicates:#,##0}:{Duplicates * 100 / TotalNodes:0}%")
                         .If(DepthCurrent >= 0, () => $" Depth={DepthCurrent:#,##0}:{DepthMax:#,##0}")
                         .If(DepthCompleted >= 0, () => $" DepthComplete={DepthCompleted:#,##0}")
                         )
            .Append($"{TotalNodes,11:#,##0} nodes at {TotalNodes / DurationInSec,7:#,##0}/s in {Elapsed.Humanize()}");

            return(builder);
        }
예제 #12
0
 protected PlainUtils CreatePlainerType(PlainUtils cloned)
 {
     cloned.FluentString = FluentString.CreatePlainerType();
     return(cloned);
 }
예제 #13
0
 public void LazyShadowToOnline()
 {
     FluentString.LazyShadowToOnline();
 }
예제 #14
0
 public void LazyOnlineToShadow()
 {
     FluentString.LazyOnlineToShadow();
 }
        public ExitConditions.Conditions Solve(SolverState state)
        {
            var full     = (MultiThreadedSolverState)state;
            var allTasks = full.Workers.Select(x => (Task)x.Task).ToArray();
            var cancel   = state.Command.CancellationToken;

            // Start and wait
            full.IsRunning = true;
            foreach (var worker in full.Workers)
            {
                worker.Task.Start();
            }

            Task statisticsTick = null;

            if (state.Command.AggProgress != null)
            {
                // Setup global/aggregate statistics and updates
                statisticsTick = Task.Run(() =>
                {
                    while (full.IsRunning)
                    {
                        Thread.Sleep(1000);
                        state.Statistics.TotalNodes = current.PoolForward.Statistics.TotalNodes
                                                      + current.PoolReverse.Statistics.TotalNodes;

                        var txt = new FluentString()
                                  .Append($"==> {state.Statistics.ToString(false, true)}")
                                  .Append($" Fwd({current.PoolForward.Statistics.TotalNodes:#,##0}|{current.QueueForward.Statistics.TotalNodes:#,##0})")
                                  .Append($" Rev({current.PoolReverse.Statistics.TotalNodes:#,##0}|{current.QueueReverse.Statistics.TotalNodes:#,##0})");
                        state.Command.AggProgress.Update(this, state, state.Statistics, txt);
                    }
                    if (state.Command.AggProgress is IDisposable dp)
                    {
                        dp.Dispose();
                    }
                });
            }

            if (!Task.WaitAll(allTasks, (int)state.Command.ExitConditions.Duration.TotalMilliseconds, cancel))
            {
                // Close down the workers as gracefully as possible
                state.Command.ExitConditions.ExitRequested = true;

                // Allow them to process the ExitRequested
                Thread.Sleep((int)TimeSpan.FromSeconds(1).TotalMilliseconds);

                // Close down any outlyers
                foreach (var task in allTasks)
                {
                    if (task.Status == TaskStatus.Running)
                    {
                        if (!task.Wait((int)TimeSpan.FromSeconds(1).TotalMilliseconds))
                        {
                            task.Dispose();
                        }
                    }
                }

                state.Exit = ExitConditions.Conditions.TimeOut;
            }
            full.IsRunning = false;
            statisticsTick?.Wait();
            state.Statistics.Completed = DateTime.Now;

            foreach (var stat in current.StatsInner)
            {
                stat.Completed = state.Statistics.Completed;
            }

            // Get solutions & Exit Conditions & Errors
            var errors = full.Workers.Select(x => x.WorkerState.Exception).Where(x => x != null).ToList();

            if (errors.Any())
            {
                throw new AggregateException(errors);
            }
            foreach (var worker in full.Workers)
            {
                worker.WorkerState.Statistics.Completed = state.Statistics.Completed;

                // Bubble up exit to owner
                state.Command.Report?.WriteLine($"WorkerExit: {worker.Name} -> {worker.WorkerState.Exit}");

                if (state.Exit == ExitConditions.Conditions.InProgress &&
                    (worker.WorkerState.Exit != ExitConditions.Conditions.InProgress && worker.WorkerState.Exit != ExitConditions.Conditions.Aborted))
                {
                    state.Exit = worker.WorkerState.Exit;
                }

                if (worker.WorkerState.HasSolution)
                {
                    if (worker.WorkerState.SolutionsNodes != null)
                    {
                        full.SolutionsNodes ??= new List <SolverNode>();
                        full.SolutionsNodes.AddRange(worker.WorkerState.SolutionsNodes);
                        state.Exit = ExitConditions.Conditions.Solution;
                    }

                    if (worker.WorkerState.SolutionsNodesReverse != null)
                    {
                        full.SolutionsNodesReverse ??= new List <SolutionChain>();
                        full.SolutionsNodesReverse.AddRange(worker.WorkerState.SolutionsNodesReverse);
                        state.Exit = ExitConditions.Conditions.Solution;
                    }
                }
            }

            // Update stats
            state.Statistics.TotalNodes = current.PoolForward.Statistics.TotalNodes
                                          + current.PoolReverse.Statistics.TotalNodes;

            SolverHelper.GetSolutions(state, true);



            if (state.Exit == ExitConditions.Conditions.Continue)
            {
                state.Exit = full.Workers.Select(x => x.WorkerState.Exit)
                             .GroupBy(x => x)
                             .OrderBy(x => x.Count())
                             .First().Key;
            }

            return(state.Exit);
        }
예제 #16
0
        public int SolverRun(BatchArgs batchArgs, SolverRun run)
        {
            var args =
                new FluentString(" ")
                .Append(batchArgs.Puzzle).Sep()
                .Append($"--solver {batchArgs.Solver}").Sep()
                .Append($"--pool {batchArgs.Pool}").Sep()
                .If(batchArgs.Min > 0, $"--min {batchArgs.Min}").Sep()
                .If(batchArgs.Sec > 0, $"--sec {batchArgs.Sec}").Sep()
                .If(batchArgs.MinR > 0, $"--min-rating {batchArgs.MinR}").Sep()
                .If(batchArgs.MaxR < 2000, $"--min-rating {batchArgs.MaxR}");

            batchArgs.Console.WriteLine($"Arguments: {args}");

            var           exitRequested = false;
            SolverCommand?executing     = null;

            // Setup: Report and cancellation
            var benchId   = DateTime.Now.ToString("s").Replace(':', '-');
            var outFile   = $"./benchmark--{benchId}.txt";
            var outTele   = $"./telemetry--{benchId}.csv";
            var outFolder = "./results/";

            if (!Directory.Exists(outFolder))
            {
                Directory.CreateDirectory(outFolder);
            }
            var info = new FileInfo(System.IO.Path.Combine(outFolder, outFile));
            var tele = new FileInfo(System.IO.Path.Combine(outFolder, outTele));


            using var report  = File.CreateText(info.FullName);
            using var repTele = File.CreateText(tele.FullName);

            System.Console.CancelKeyPress += (o, e) =>
            {
                report.Flush();
                batchArgs.Console.WriteLine("Ctrl+C detected; cancel requested");

                if (executing != null)
                {
                    executing.ExitConditions.ExitRequested = true;
                }
                exitRequested = true;
            };

            ISokobanSolutionRepository?solutionRepo = File.Exists("./solutions.json") && !DevHelper.IsDebug()
                ? new JsonSokobanSolutionRepository("./solutions.json")
                : null;
            ISolverRunTracking?runTracking = null;

            var results    = new List <(Strategy, List <SolverResultSummary>)>();
            var perm       = GetPermutations(batchArgs.Solver, batchArgs.Pool).ToList();
            var countStrat = 0;

            foreach (var strat in perm)
            {
                countStrat++;
                batchArgs.Console.WriteLine($"(Strategy {countStrat}/{perm.Count}) {strat}");

                var ioc = new SolverContainerByType(new Dictionary <Type, Func <Type, object> >()
                {
                    { typeof(ISolverPool), _ => PoolFactory(strat.Pool) },
                    { typeof(ISolverQueue), _ => new SolverQueueConcurrent() },
                    { typeof(ISolverRunTracking), _ => runTracking },
                    { typeof(ISokobanSolutionRepository), _ => solutionRepo },
                });
                var solverCommand = new SolverCommand
                {
                    ServiceProvider = ioc,
                    ExitConditions  = new ExitConditions()
                    {
                        Duration       = TimeSpan.FromMinutes(batchArgs.Min).Add(TimeSpan.FromSeconds(batchArgs.Sec)),
                        MemAvail       = DevHelper.GiB_1 / 2, // Stops the machine hanging / swapping to death
                        StopOnSolution = true,
                    },
                    AggProgress = new ConsoleProgressNotifier(repTele),
                    CheckAbort  = x => exitRequested,
                };


                var runner = new SingleSolverBatchSolveComponent(
                    new TextWriterAdapter(report),
                    batchArgs.Console,
                    solutionRepo,
                    runTracking,
                    5,
                    false);

                var solverInstance = SolverFactory(strat.Solver, ioc);
                var summary        = runner.Run(run, solverCommand, solverInstance, false, batchArgs);
                results.Add((strat, summary));
            }

            // Header
            var extras = new Dictionary <string, string>()
            {
                { "Args", args },
                { "Report", info.FullName }
            };

            DevHelper.WriteFullDevelopmentContext(report, extras);
            DevHelper.WriteFullDevelopmentContext(System.Console.Out, extras);

            // Body
            var reportRow = GenerateReport(results).ToList();

            MapToReporting.Create <SummaryLine>()
            .AddColumn("Solver", x => x.Strategy.Solver)
            .AddColumn("Pool", x => x.Strategy.Pool)
            .AddColumn("Puzzle", x => x.Result.Puzzle.Ident)
            .AddColumn("State", x => x.Result.Exited)
            .AddColumn("Solutions", x => (x.Result.Solutions?.Count ?? 0) == 0 ? null : (int?)x.Result.Solutions.Count)
            .AddColumn("Statistics", x =>
                       x.Result.Exited == ExitConditions.Conditions.Error
                                  ? x.Result.Exited.ToString()
                                  : x.Result.Statistics?.ToString(false, true)
                       )
            .RenderTo(reportRow, new MapToReportingRendererText(), report)
            .RenderTo(reportRow, new MapToReportingRendererText(), System.Console.Out);

            return(results.Any(x => x.Item2.Any(y => y.Exited == ExitConditions.Conditions.Error)) ? -1 : 0); // All exceptions
        }