Beispiel #1
0
    private void AssertRuleDoesNotMatchCondtitional(
        string ruleText,
        int[] sourceSymbols        = null,
        float[][] sourceParameters = null,
        string axiom = null,
        int ruleParamMemoryStartIndex = 0,
        int matchIndex            = 0,
        int paramTempMemorySize   = 0,
        float[] globalParams      = null,
        string[] globalParamNames = null,
        string includedSymbols    = "[]ABCDE"
        )
    {
        var totalIncluded = new HashSet <int>(includedSymbols.Select(x => (int)x));

        globalParamNames  = globalParamNames ?? new string[0];
        using var symbols = new DependencyTracker <SymbolString <float> >(
                  axiom == null ?
                  new SymbolString <float>(sourceSymbols, sourceParameters)
            : SymbolString <float> .FromString(axiom, Allocator.Persistent)
                  );
        var ruleFromString = new BasicRule(
            RuleParser.ParseToRule(ruleText, x => x, globalParameters: globalParamNames),
            '[', ']');

        using var ruleNativeData = new SystemLevelRuleNativeData(new[] { ruleFromString });
        var nativeWriter = new SymbolSeriesMatcherNativeDataWriter();

        ruleFromString.WriteDataIntoMemory(ruleNativeData, nativeWriter);

        globalParams           = globalParams ?? new float[0];
        using var globalNative = new NativeArray <float>(globalParams, Allocator.Persistent);

        using var paramMemory = new NativeArray <float>(paramTempMemorySize, Allocator.Persistent);
        using var branchCache = new SymbolStringBranchingCache('[', ']', new[] { totalIncluded }, ruleNativeData);
        branchCache.BuildJumpIndexesFromSymbols(symbols);
        var random          = new Unity.Mathematics.Random();
        var matchSingleData = new LSystemSingleSymbolMatchData
        {
            isTrivial = false,
            tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(ruleParamMemoryStartIndex)
        };

        var potentialMatch = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional(
            branchCache,
            symbols.Data,
            matchIndex,
            paramMemory,
            matchSingleData.tmpParameterMemorySpace.index,
            ref matchSingleData,
            new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5),
            globalNative,
            ruleNativeData.dynamicOperatorMemory,
            ref random,
            ruleNativeData.ruleOutcomeMemorySpace
            );

        Assert.IsFalse(potentialMatch);
    }
 public void FindsBranchForwardLinksCorrectlyWhenBranchingAtSameIndexAsCharacterCodeForBranchingSymbol()
 {
     using var targetString   = new DependencyTracker <SymbolString <float> >(SymbolString <float> .FromString("[&E][&&E]&EEEE[&[EE]E][&&[EE]E]&EEEE[&[EEEE]EE][&&[EEEE]EE]&EEEA[&[EEEEEE]E[E]E[E]][&&[EEEEEE]E[E]E[E]]"));
     using var branchingCache = new SymbolStringBranchingCache('[', ']', new SystemLevelRuleNativeData());
     branchingCache.BuildJumpIndexesFromSymbols(targetString);
     Assert.AreEqual(64, branchingCache.FindOpeningBranchIndexReadonly(82));
     Assert.AreEqual(86, branchingCache.FindOpeningBranchIndexReadonly(93));
 }
 public void FindsClosingBranchLinks()
 {
     using var targetString   = new DependencyTracker <SymbolString <float> >(SymbolString <float> .FromString("A[AA]AAA[A[AAA[A]]]A"));
     using var branchingCache = new SymbolStringBranchingCache('[', ']', new SystemLevelRuleNativeData());
     branchingCache.BuildJumpIndexesFromSymbols(targetString);
     Assert.AreEqual(4, branchingCache.FindClosingBranchIndexReadonly(1));
     Assert.AreEqual(17, branchingCache.FindClosingBranchIndexReadonly(10));
     Assert.AreEqual(18, branchingCache.FindClosingBranchIndexReadonly(8));
 }
    private void AssertBackwardsMatch(
        string target,
        string matcher,
        bool shouldMatch,
        string includeSymbols              = "[]ABCDEFJ",
        int parameterMemorySize            = 10,
        float[] expectedCapturedParameters = null,
        int indexInTarget = -1)
    {
        var includedSymbolSet = includeSymbols.Select(x => (int)x);

        var prefixBuilder = SymbolSeriesPrefixBuilder.Parse(matcher);

        using var nativeData = new SystemLevelRuleNativeData(new RuleDataRequirements
        {
            prefixNodes = prefixBuilder.RequiredNodeMemorySpace
        });
        var writer = new SymbolSeriesMatcherNativeDataWriter();

        var seriesMatcher = prefixBuilder.BuildIntoManagedMemory(nativeData, writer);

        using var targetString   = new DependencyTracker <SymbolString <float> >(SymbolString <float> .FromString(target));
        using var branchingCache = new SymbolStringBranchingCache(
                  '[', ']',
                  includedSymbolSet == null ? new HashSet <int> [0] : new[] { new HashSet <int>(includedSymbolSet) },
                  nativeData);
        branchingCache.BuildJumpIndexesFromSymbols(targetString);
        using var parameterMemory = new NativeArray <float>(parameterMemorySize, Allocator.Persistent);


        var realIndex  = indexInTarget < 0 ? indexInTarget + targetString.Data.Length : indexInTarget;
        var hasMatched = branchingCache.MatchesBackwards(
            branchingCache.includeSymbols[0],
            realIndex,
            seriesMatcher,
            targetString.Data,
            0,
            parameterMemory,
            out var copiedParams);

        if (shouldMatch != hasMatched)
        {
            Assert.Fail($"Expected '{matcher}' to {(shouldMatch ? "" : "not ")}match backwards from {indexInTarget} in '{target}'");
        }
        if (shouldMatch && expectedCapturedParameters != null)
        {
            Assert.AreEqual(expectedCapturedParameters.Length, copiedParams);
            for (int i = 0; i < expectedCapturedParameters.Length; i++)
            {
                Assert.AreEqual(expectedCapturedParameters[i], parameterMemory[i]);
            }
        }
    }
Beispiel #5
0
        public LSystemParameterSizeCountingCompletable(
            LSystemState <float> systemState,
            DependencyTracker <SystemLevelRuleNativeData> lSystemNativeData,
            float[] globalParameters,
            ISet <int>[] includedCharactersByRuleIndex,
            CustomRuleSymbols customSymbols,
            JobHandle parameterModificationJobDependency)
        {
            currentJobHandle = default;

            this.globalParameters            = globalParameters;
            this.paramModificationDependency = parameterModificationJobDependency;

            this.systemState   = systemState;
            this.customSymbols = customSymbols;
            nativeData         = lSystemNativeData;

            // 1.
            UnityEngine.Profiling.Profiler.BeginSample("Paramter counts");

            UnityEngine.Profiling.Profiler.BeginSample("allocating");
            matchSingletonData = new NativeArray <LSystemSingleSymbolMatchData>(systemState.currentSymbols.Data.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            parameterTotalSum  = new NativeArray <int>(1, Allocator.TempJob);
            UnityEngine.Profiling.Profiler.EndSample();

            var memorySizeJob = new SymbolStringMemoryRequirementsJob
            {
                matchSingletonData          = matchSingletonData,
                memoryRequirementsPerSymbol = nativeData.Data.maxParameterMemoryRequirementsPerSymbol,
                parameterTotalSum           = parameterTotalSum,
                sourceSymbolString          = systemState.currentSymbols.Data
            };

            currentJobHandle = memorySizeJob.Schedule();
            systemState.currentSymbols.RegisterDependencyOnData(currentJobHandle);
            nativeData.RegisterDependencyOnData(currentJobHandle);


            UnityEngine.Profiling.Profiler.EndSample();

            // 2.1
            UnityEngine.Profiling.Profiler.BeginSample("branch cache");
            branchingCache = new SymbolStringBranchingCache(
                customSymbols.branchOpenSymbol,
                customSymbols.branchCloseSymbol,
                includedCharactersByRuleIndex,
                nativeData.Data);
            branchingCache.BuildJumpIndexesFromSymbols(systemState.currentSymbols);
            UnityEngine.Profiling.Profiler.EndSample();
        }
    private void AssertForwardsMatch(
        string target,
        string matcher,
        bool shouldMatch                   = true,
        int indexInTarget                  = 0,
        int parameterMemorySize            = 10,
        float[] expectedCapturedParameters = null,
        string message        = null,
        string includeSymbols = "[]ABCDEFGJKZ")
    {
        var seriesMatcher = SymbolSeriesGraphTests.GenerateSingleMatcher(matcher, out var nativeData);

        using var nativeDataDisposable = nativeData;
        using var targetString         = new DependencyTracker <SymbolString <float> >(SymbolString <float> .FromString(target));
        using var branchingCache       = new SymbolStringBranchingCache(
                  '[', ']',
                  includeSymbols == null ? new HashSet <int> [0] : new[] { new HashSet <int>(includeSymbols.Select(x => (int)x)) },
                  nativeDataDisposable);
        branchingCache.BuildJumpIndexesFromSymbols(targetString);
        using var parameterMemory = new NativeArray <float>(parameterMemorySize, Allocator.Persistent);

        var matches = branchingCache.MatchesForward(
            branchingCache.includeSymbols[0],
            indexInTarget,
            seriesMatcher,
            targetString.Data,
            0,
            parameterMemory,
            out var copiedParams,
            new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5));

        if (shouldMatch != matches)
        {
            Assert.Fail($"Expected '{matcher}' to {(shouldMatch ? "" : "not ")}match forwards retaining order from {indexInTarget} in '{target}'{(message == null ? "" : '\n' + message)}");
        }
        if (shouldMatch && expectedCapturedParameters != null)
        {
            Assert.AreEqual(expectedCapturedParameters.Length, copiedParams, "captured parameter length mismatch");
            for (int i = 0; i < expectedCapturedParameters.Length; i++)
            {
                Assert.AreEqual(expectedCapturedParameters[i], parameterMemory[i]);
            }
        }
    }
Beispiel #7
0
    public void BasicRuleRejectsApplicationIfAnyParameters()
    {
        var ruleFromString = new BasicRule(
            RuleParser.ParseToRule("A -> AB", x => x),
            '[', ']');
        var totalIncluded = new HashSet <int>("[]AB".Select(x => (int)x));

        using var ruleNativeData = new SystemLevelRuleNativeData(new[] { ruleFromString });
        var nativeWriter = new SymbolSeriesMatcherNativeDataWriter();

        ruleFromString.WriteDataIntoMemory(ruleNativeData, nativeWriter);

        var symbols = new DependencyTracker <SymbolString <float> >(
            new SymbolString <float>(new int[] { 'A' }, new float[][] { new float[0] })
            );

        try
        {
            var globalParams = new float[0];
            using var globalNative = new NativeArray <float>(globalParams, Allocator.Persistent);
            using var paramMemory  = new NativeArray <float>(0, Allocator.Persistent);
            using var branchCache  = new SymbolStringBranchingCache('[', ']', new[] { totalIncluded }, ruleNativeData);
            branchCache.BuildJumpIndexesFromSymbols(symbols);
            var random          = new Unity.Mathematics.Random();
            var matchSingleData = new LSystemSingleSymbolMatchData
            {
                isTrivial = false,
                tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(0)
            };

            var preMatchSuccess = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional(
                branchCache,
                symbols.Data,
                0,
                paramMemory,
                matchSingleData.tmpParameterMemorySpace.index,
                ref matchSingleData,
                new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5),
                globalNative,
                ruleNativeData.dynamicOperatorMemory,
                ref random,
                ruleNativeData.ruleOutcomeMemorySpace
                );
            Assert.IsTrue(preMatchSuccess);
            Assert.AreEqual(0, matchSingleData.selectedReplacementPattern);
            Assert.AreEqual(0, matchSingleData.tmpParameterMemorySpace.length);
            Assert.AreEqual(2, matchSingleData.replacementSymbolIndexing.length);
            Assert.AreEqual(0, matchSingleData.replacementParameterIndexing.length);

            var symbolRawData = symbols.Data;
            symbolRawData.parameters[0] = new JaggedIndexing
            {
                index  = 0,
                length = 1
            };

            matchSingleData = new LSystemSingleSymbolMatchData
            {
                isTrivial = false,
                tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(0)
            };
            preMatchSuccess = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional(
                branchCache,
                symbols.Data,
                0,
                paramMemory,
                matchSingleData.tmpParameterMemorySpace.index,
                ref matchSingleData,
                new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5),
                globalNative,
                ruleNativeData.dynamicOperatorMemory,
                ref random,
                ruleNativeData.ruleOutcomeMemorySpace
                );
            Assert.IsFalse(preMatchSuccess);
        }
        finally
        {
            symbols.Dispose();
        }
    }
Beispiel #8
0
        public LSystemSymbolReplacementCompletable(
            Unity.Mathematics.Random randResult,
            LSystemState <float> lastSystemState,
            int totalNewSymbolSize,
            int totalNewParamSize,
            NativeArray <float> globalParamNative,
            NativeArray <float> tmpParameterMemory,
            NativeArray <LSystemSingleSymbolMatchData> matchSingletonData,
            DependencyTracker <SystemLevelRuleNativeData> nativeData,
            SymbolStringBranchingCache branchingCache,
            CustomRuleSymbols customSymbols)
        {
            this.lastSystemState    = lastSystemState;
            this.matchSingletonData = matchSingletonData;
            this.branchingCache     = branchingCache;
            UnityEngine.Profiling.Profiler.BeginSample("allocating");
            target = new SymbolString <float>(totalNewSymbolSize, totalNewParamSize, Allocator.Persistent);
            UnityEngine.Profiling.Profiler.EndSample();

            this.randResult = randResult;

            this.nativeData = nativeData;

            // 5
            UnityEngine.Profiling.Profiler.BeginSample("generating replacements");

            var replacementJob = new RuleReplacementJob
            {
                globalParametersArray = globalParamNative,

                parameterMatchMemory = tmpParameterMemory,
                matchSingletonData   = matchSingletonData,

                sourceData            = lastSystemState.currentSymbols.Data,
                structExpressionSpace = nativeData.Data.structExpressionMemorySpace,
                globalOperatorData    = nativeData.Data.dynamicOperatorMemory,
                replacementSymbolData = nativeData.Data.replacementsSymbolMemorySpace,
                outcomeData           = nativeData.Data.ruleOutcomeMemorySpace,

                targetData = target,
                blittableRulesByTargetSymbol = nativeData.Data.blittableRulesByTargetSymbol,
                branchingCache = branchingCache,
                customSymbols  = customSymbols
            };

            currentJobHandle = replacementJob.Schedule(
                matchSingletonData.Length,
                100
                );

            if (customSymbols.hasDiffusion && !customSymbols.independentDiffusionUpdate)
            {
                diffusionHelper = new DiffusionWorkingDataPack(10, 5, 2, customSymbols, Allocator.TempJob);
                var diffusionJob = new ParallelDiffusionReplacementJob
                {
                    matchSingletonData = matchSingletonData,
                    sourceData         = lastSystemState.currentSymbols.Data,
                    targetData         = target,
                    customSymbols      = customSymbols,
                    working            = diffusionHelper
                };
                currentJobHandle = JobHandle.CombineDependencies(
                    currentJobHandle,
                    diffusionJob.Schedule()
                    );
            }
            // only parameter modifications beyond this point
            lastSystemState.currentSymbols.RegisterDependencyOnData(currentJobHandle);
            nativeData.RegisterDependencyOnData(currentJobHandle);

            currentJobHandle = JobHandle.CombineDependencies(
                JobHandle.CombineDependencies(
                    ScheduleIdAssignmentJob(currentJobHandle, customSymbols, lastSystemState),
                    ScheduleIndependentDiffusion(currentJobHandle, customSymbols)
                    ),
                JobHandle.CombineDependencies(
                    ScheduleAutophagyJob(currentJobHandle, customSymbols),
                    ScheduleImmaturityJob(currentJobHandle)
                    ));

            UnityEngine.Profiling.Profiler.EndSample();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="lastSystemState"></param>
        /// <param name="lSystemNativeData"></param>
        /// <param name="globalParameters"></param>
        /// <param name="maxMemoryRequirementsPerSymbol"></param>
        /// <param name="branchOpenSymbol"></param>
        /// <param name="branchCloseSymbol"></param>
        /// <param name="includedCharactersByRuleIndex"></param>
        /// <param name="customSymbols"></param>
        /// <param name="parameterModificationJobDependency">A dependency on a job which only makes changes to the parameters of the source symbol string.
        ///     the symbols themselves must be constant</param>
        public LSystemRuleMatchCompletable(
            NativeArray <LSystemSingleSymbolMatchData> matchSingletonData,
            int parameterTotalSum,
            SymbolStringBranchingCache branchingCache,
            LSystemState <float> lastSystemState,
            DependencyTracker <SystemLevelRuleNativeData> lSystemNativeData,
            float[] globalParameters,
            CustomRuleSymbols customSymbols,
            JobHandle parameterModificationJobDependency)
        {
            this.customSymbols   = customSymbols;
            this.lastSystemState = lastSystemState;
            randResult           = lastSystemState.randomProvider;
            nativeData           = lSystemNativeData;

            this.matchSingletonData = matchSingletonData;
            this.branchingCache     = branchingCache;

            // 1.
            UnityEngine.Profiling.Profiler.BeginSample("allocating");
            tmpParameterMemory = new NativeArray <float>(parameterTotalSum, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            globalParamNative  = new NativeArray <float>(globalParameters, Allocator.Persistent);
            UnityEngine.Profiling.Profiler.EndSample();

            // 2.
            UnityEngine.Profiling.Profiler.BeginSample("matching");


            var prematchJob = new RuleCompleteMatchJob
            {
                matchSingletonData = matchSingletonData,

                sourceData         = lastSystemState.currentSymbols.Data,
                tmpParameterMemory = tmpParameterMemory,

                globalOperatorData = nativeData.Data.dynamicOperatorMemory,
                outcomes           = nativeData.Data.ruleOutcomeMemorySpace,
                globalParams       = globalParamNative,

                blittableRulesByTargetSymbol = nativeData.Data.blittableRulesByTargetSymbol,
                branchingCache = branchingCache,
                seed           = randResult.NextUInt()
            };

            var matchingJobHandle = prematchJob.ScheduleBatch(
                matchSingletonData.Length,
                100,
                parameterModificationJobDependency);


            UnityEngine.Profiling.Profiler.EndSample();

            // 4.
            UnityEngine.Profiling.Profiler.BeginSample("replacement counting");

            UnityEngine.Profiling.Profiler.BeginSample("allocating");
            totalSymbolCount          = new NativeArray <int>(1, Allocator.Persistent);
            totalSymbolParameterCount = new NativeArray <int>(1, Allocator.Persistent);
            UnityEngine.Profiling.Profiler.EndSample();

            var totalSymbolLengthJob = new RuleReplacementSizeJob
            {
                matchSingletonData        = matchSingletonData,
                totalResultSymbolCount    = totalSymbolCount,
                totalResultParameterCount = totalSymbolParameterCount,
                sourceData    = lastSystemState.currentSymbols.Data,
                customSymbols = customSymbols
            };

            currentJobHandle = totalSymbolLengthJob.Schedule(matchingJobHandle);
            lastSystemState.currentSymbols.RegisterDependencyOnData(currentJobHandle);
            nativeData.RegisterDependencyOnData(currentJobHandle);

            UnityEngine.Profiling.Profiler.EndSample();
        }