public void CreateQuiverInPlaneAnalysisResults_IQPAnalysisResultsOfTVertex_SetsMainResultCorrectly() { var defaultMaximalReps = new Dictionary <int, IEnumerable <Path <int> > >(); var defaultNakayamaPermutation = new NakayamaPermutation <int>(new Dictionary <int, int>()); var defaultLongestPath = new Path <int>(startingPoint: 1); var qpAnalysisResults = CreateQPAnalysisResults( QPAnalysisMainResults.Success, defaultMaximalReps, defaultNakayamaPermutation, defaultLongestPath); var results = AnalysisResultsFactory.CreateQuiverInPlaneAnalysisResults(qpAnalysisResults); Assert.That(results.MainResults, Is.EqualTo(QuiverInPlaneAnalysisMainResults.Success)); qpAnalysisResults = CreateQPAnalysisResults( QPAnalysisMainResults.Success, defaultMaximalReps, defaultNakayamaPermutation, defaultLongestPath); results = AnalysisResultsFactory.CreateQuiverInPlaneAnalysisResults(qpAnalysisResults); Assert.That(results.MainResults, Is.EqualTo(QuiverInPlaneAnalysisMainResults.Success)); Assert.That(results.MainResults.IndicatesSelfInjectivity()); qpAnalysisResults = CreateQPAnalysisResults( QPAnalysisMainResults.Aborted, null, null, defaultLongestPath); results = AnalysisResultsFactory.CreateQuiverInPlaneAnalysisResults(qpAnalysisResults); Assert.That(results.MainResults, Is.EqualTo(QuiverInPlaneAnalysisMainResults.QPAnalysisAborted)); qpAnalysisResults = CreateQPAnalysisResults( QPAnalysisMainResults.Cancelled, null, null, defaultLongestPath); results = AnalysisResultsFactory.CreateQuiverInPlaneAnalysisResults(qpAnalysisResults); Assert.That(results.MainResults, Is.EqualTo(QuiverInPlaneAnalysisMainResults.QPAnalysisCancelled)); qpAnalysisResults = CreateQPAnalysisResults( QPAnalysisMainResults.NotCancellative, null, null, defaultLongestPath); results = AnalysisResultsFactory.CreateQuiverInPlaneAnalysisResults(qpAnalysisResults); Assert.That(results.MainResults, Is.EqualTo(QuiverInPlaneAnalysisMainResults.QPIsNotCancellative)); QPAnalysisResults <int> CreateQPAnalysisResults( QPAnalysisMainResults mainResult, Dictionary <int, IEnumerable <Path <int> > > maximalPathRepresentatives, NakayamaPermutation <int> nakayamaPermutation, Path <int> longestPathEncountered) { return(new QPAnalysisResults <int>(mainResult, maximalPathRepresentatives, nakayamaPermutation, longestPathEncountered)); } }
/// <summary> /// Initializes a new instance of the <see cref="AnalysisResults{TVertex, TMainResult}"/> class. /// </summary> /// <param name="mainResult">The main result.</param> /// <param name="maximalPathRepresentatives">A dictionary mapping every vertex of the /// quiver to a collection of representatives of all maximal non-zero equivalence classes /// of paths starting at the vertex, or <see langword="null"/> depending on whether the /// analysis was successful.</param> /// <param name="nakayamaPermutation">The Nakayama permutation for the analyzed /// "gadget" or <see langword="null"/>, depending on whether the analysis was /// successful and the gadget has a Nakayama permutation.</param> /// <param name="longestPathEncountered">A path of maximal length of the paths encountered /// during the analysis, or <see langword="null"/> if no path was encountered (e.g., if a /// quiver-in-plane analysis is done on a non-plane quiver, or if the quiver is empty).</param> protected AnalysisResults( TMainResult mainResult, IReadOnlyDictionary <TVertex, IEnumerable <Path <TVertex> > > maximalPathRepresentatives, NakayamaPermutation <TVertex> nakayamaPermutation, Path <TVertex> longestPathEncountered) { MainResults = mainResult; MaximalPathRepresentatives = maximalPathRepresentatives; NakayamaPermutation = nakayamaPermutation; LongestPathEncountered = longestPathEncountered; }
/// <summary> /// Initializes a new instance of the <see cref="SemimonomialUnboundQuiverAnalysisResults{TVertex}"/> class. /// </summary> /// <param name="mainResults">The main results.</param> /// <param name="maximalPathRepresentatives">A dictionary mapping every vertex of the /// quiver to a collection of representatives of all maximal non-zero equivalence classes /// of paths starting at the vertex, or <see langword="null"/> depending on whether the /// analysis was successful.</param> /// <param name="nakayamaPermutation">The Nakayama permutation for the analyzed /// semimonomial unbound quiver or /// <see langword="null"/>, depending on whether the analysis was successful and the /// semimonomial unbound quiver has a Nakayama permutation.</param> /// <param name="longestPathEncountered">A path of maximal length of the paths encountered /// during the analysis, or <see langword="null"/> if no path was encountered during the /// analysis (i.e., if the quiver was empty).</param> public SemimonomialUnboundQuiverAnalysisResults( SemimonomialUnboundQuiverAnalysisMainResults mainResults, IReadOnlyDictionary <TVertex, IEnumerable <Path <TVertex> > > maximalPathRepresentatives, NakayamaPermutation <TVertex> nakayamaPermutation, Path <TVertex> longestPathEncountered) : base(mainResults, maximalPathRepresentatives, nakayamaPermutation, longestPathEncountered) { if (mainResults.HasFlag(SemimonomialUnboundQuiverAnalysisMainResults.Success) && maximalPathRepresentatives is null) { throw new ArgumentNullException(nameof(maximalPathRepresentatives)); } if (mainResults.IndicatesSelfInjectivity() && nakayamaPermutation is null) { throw new ArgumentNullException(nameof(nakayamaPermutation)); } }
/// <summary> /// Analyzes a semimonomial unbound quiver with a default computer of maximal nonzero /// equivalence class representatives. /// </summary> /// <typeparam name="TVertex">The type of the vertices of the quiver.</typeparam> /// <param name="unboundQuiver">The unbound quiver.</param> /// <param name="settings">The settings for the analysis.</param> /// <param name="computer">A computer of maximal nonzero equivalence class representatives.</param> /// <returns>The results of the analysis.</returns> /// <exception cref="ArgumentNullException"><paramref name="unboundQuiver"/> is /// <see langword="null"/>, or <paramref name="settings"/> is <see langword="null"/>, /// or <paramref name="computer"/> is <see langword="null"/>.</exception> /// <exception cref="NotSupportedException">The semimonomial ideal of /// <paramref name="unboundQuiver"/> has two distinct non-monomial generators /// <c>p1 - q1</c> and <c>p2 - q2</c> where <c>p1, q1, p2, q2</c> are not all distinct.</exception> /// <exception cref="ArgumentException">The semimonomial ideal of /// <paramref name="unboundQuiver"/> has a non-monomial generator <c>p - q</c> where the /// paths <c>p</c> and <c>q</c> do not have the same endpoints.</exception> public ISemimonomialUnboundQuiverAnalysisResults <TVertex> Analyze <TVertex>( SemimonomialUnboundQuiver <TVertex> unboundQuiver, SemimonomialUnboundQuiverAnalysisSettings settings, IMaximalNonzeroEquivalenceClassRepresentativeComputer computer) where TVertex : IEquatable <TVertex>, IComparable <TVertex> { if (unboundQuiver is null) { throw new ArgumentNullException(nameof(unboundQuiver)); } if (settings is null) { throw new ArgumentNullException(nameof(settings)); } if (computer is null) { throw new ArgumentNullException(nameof(computer)); } var computationSettings = AnalysisSettingsFactory.CreateMaximalNonzeroEquivalenceClassRepresentativeComputationSettings(settings); var transformationRuleTreeCreator = new TransformationRuleTreeCreator(); var transformationRuleTree = transformationRuleTreeCreator.CreateTransformationRuleTree(unboundQuiver); var maximalPathRepresentatives = new Dictionary <TVertex, IEnumerable <Path <TVertex> > >(); var nakayamaPermutationDict = new Dictionary <TVertex, TVertex>(); var mainResults = SemimonomialUnboundQuiverAnalysisMainResults.None; Path <TVertex> longestPath = null; foreach (var startingVertex in unboundQuiver.Quiver.Vertices) { var representativesResult = computer.ComputeMaximalNonzeroEquivalenceClassRepresentativesStartingAt(unboundQuiver.Quiver, startingVertex, transformationRuleTree, computationSettings); if (longestPath is null || representativesResult.LongestPathEncountered.Length > longestPath.Length) { longestPath = representativesResult.LongestPathEncountered; } if (representativesResult.WeakCancellativityFailureDetected) { mainResults |= SemimonomialUnboundQuiverAnalysisMainResults.NotWeaklyCancellative; } if (representativesResult.CancellativityFailureDetected) { mainResults |= SemimonomialUnboundQuiverAnalysisMainResults.NotCancellative; } if (representativesResult.TooLongPathEncountered) { mainResults |= SemimonomialUnboundQuiverAnalysisMainResults.Aborted; } if ((representativesResult.WeakCancellativityFailureDetected && settings.TerminateEarlyIfWeakCancellativityFails) || (representativesResult.CancellativityFailureDetected && settings.TerminateEarlyIfCancellativityFails) || (representativesResult.TooLongPathEncountered)) { return(new SemimonomialUnboundQuiverAnalysisResults <TVertex>(mainResults, null, null, longestPath)); } var maximalNonzeroEquivalenceClassRepresentatives = representativesResult.MaximalNonzeroEquivalenceClassRepresentatives; maximalPathRepresentatives[startingVertex] = maximalNonzeroEquivalenceClassRepresentatives; int numMaximalNonzeroPathClasses = maximalNonzeroEquivalenceClassRepresentatives.Count(); Debug.Assert(numMaximalNonzeroPathClasses > 0, "Analysis with starting vertex found 0 maximal nonzero classes."); if (numMaximalNonzeroPathClasses > 1) { mainResults |= SemimonomialUnboundQuiverAnalysisMainResults.MultipleMaximalNonzeroClasses; if (settings.TerminateEarlyOnMultiDimensionalSocle) { return(new SemimonomialUnboundQuiverAnalysisResults <TVertex>(mainResults, null, null, longestPath)); } } else { var endingPoint = maximalNonzeroEquivalenceClassRepresentatives.Single().EndingPoint; // Check if the tentative Nakayama permutation fails to be injective. if (nakayamaPermutationDict.ContainsValue(endingPoint)) { mainResults |= SemimonomialUnboundQuiverAnalysisMainResults.NonInjectiveTentativeNakayamaPermutation; if (settings.TerminateEarlyIfNakayamaPermutationFails) { return(new SemimonomialUnboundQuiverAnalysisResults <TVertex>(mainResults, null, null, longestPath)); } } else { nakayamaPermutationDict[startingVertex] = endingPoint; } } } mainResults |= SemimonomialUnboundQuiverAnalysisMainResults.Success; NakayamaPermutation <TVertex> nakayamaPermutation = null; if (mainResults.IndicatesSelfInjectivity()) { nakayamaPermutation = new NakayamaPermutation <TVertex>(nakayamaPermutationDict); } return(new SemimonomialUnboundQuiverAnalysisResults <TVertex>(mainResults, maximalPathRepresentatives, nakayamaPermutation, longestPath)); }