public void ParsedRuleParsesStringDefinitionWithExoticCharacter() { var ruleFromString = RuleParser.ParseToRule("- -> AB"); Assert.AreEqual("-", ruleFromString.TargetSymbolString()); Assert.AreEqual("AB", ruleFromString.ReplacementSymbolString()); }
public void ParsedRuleParsesStringDefinition() { var ruleFromString = RuleParser.ParseToRule("A -> AB"); Assert.AreEqual("A", ruleFromString.TargetSymbolString()); Assert.AreEqual("AB", ruleFromString.ReplacementSymbolString()); }
public void ParsedRuleParsesStringDefinitionWithNovelCharacters() { var ruleFromString = RuleParser.ParseToRule("A -> F-[[X]+X]+F[+FX]-X"); Assert.AreEqual("A", ruleFromString.TargetSymbolString()); Assert.AreEqual("F-[[X]+X]+F[+FX]-X", ruleFromString.ReplacementSymbolString()); }
public void ParsesRuleWithInputParameters() { var ruleFromString = RuleParser.ParseToRule("A(x, y) -> B"); Assert.AreEqual("A(x, y)", ruleFromString.TargetSymbolString()); Assert.AreEqual("B", ruleFromString.ReplacementSymbolString()); }
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 RuleWithNoReplacementValidZeroLengthReplacement() { var ruleFromString = RuleParser.ParseToRule("A(x) ->"); Assert.AreEqual("A(x)", ruleFromString.TargetSymbolString()); Assert.AreEqual(0, ruleFromString.replacementSymbols.Length); Assert.AreEqual("", ruleFromString.ReplacementSymbolString()); }
public void ParsesRuleWithFullContextCharacterMatch() { var ruleFromString = RuleParser.ParseToRule("A < B > C -> A"); Assert.AreEqual(1, ruleFromString.forwardsMatch.Length); Assert.AreEqual(1, ruleFromString.backwardsMatch.Length); Assert.AreEqual("A < B > C", ruleFromString.TargetSymbolString()); Assert.AreEqual("A", ruleFromString.ReplacementSymbolString()); }
public void ParsesRuleWithParametersAndReplacementParametersAndComplexExpression() { var ruleFromString = RuleParser.ParseToRule("A(x, y) -> B(y + (y - x) * y)"); Assert.AreEqual("A(x, y)", ruleFromString.TargetSymbolString()); Assert.AreEqual(1, ruleFromString.replacementSymbols.Length); Assert.AreEqual('B', ruleFromString.replacementSymbols[0].targetSymbol); Assert.AreEqual(1, ruleFromString.replacementSymbols[0].evaluators.Length); Assert.AreEqual(4 + (4 - 30) * 4, ruleFromString.replacementSymbols[0].evaluators[0].DynamicInvoke(30, 4)); }
public void ParsesRuleWithParametersAndReplacementParameters() { var ruleFromString = RuleParser.ParseToRule("A(x, y) -> B(y)"); Assert.AreEqual("A(x, y)", ruleFromString.TargetSymbolString()); Assert.AreEqual(1, ruleFromString.replacementSymbols.Length); Assert.AreEqual('B', ruleFromString.replacementSymbols[0].targetSymbol); Assert.AreEqual(1, ruleFromString.replacementSymbols[0].evaluators.Length); Assert.AreEqual(7331, ruleFromString.replacementSymbols[0].evaluators[0].DynamicInvoke(1337, 7331)); }
public void ParsesRuleWithPrefixContextAndParameters() { var ruleFromString = RuleParser.ParseToRule("B(x) > A(y, z) -> B"); Assert.AreEqual(1, ruleFromString.forwardsMatch.Length); Assert.AreEqual(1, ruleFromString.coreSymbol.parameterLength); Assert.AreEqual(2, ruleFromString.forwardsMatch[0].parameterLength); Assert.AreEqual("B(x) > A(y, z)", ruleFromString.TargetSymbolString()); Assert.AreEqual("B", ruleFromString.ReplacementSymbolString()); }
public void ParsedRuleProbabilityFromExpression() { var ruleFromString = RuleParser.ParseToRule("P(0.5 - 0.3) | A -> AB"); Assert.AreEqual("A", ruleFromString.TargetSymbolString()); Assert.AreEqual("AB", ruleFromString.ReplacementSymbolString()); Assert.IsAssignableFrom <ParsedStochasticRule>(ruleFromString); var stochasticRule = ruleFromString as ParsedStochasticRule; Assert.AreEqual(0.2f, stochasticRule.probability, 1e-6); }
public void RuleWithOneTooFewParensThrowsMeaninfulException() { var ruleString = "A(x) -> B(x + (y)"; try { RuleParser.ParseToRule(ruleString); } catch (SyntaxException e) { Assert.AreEqual(17, e.errorStartIndex); Assert.AreEqual(ruleString, e.ruleText); } }
public void RuleWithInvalidUnaryOperatorThrowsMeaninfulException() { var ruleString = "A(x, y) -> B(x + / y)"; try { RuleParser.ParseToRule(ruleString); } catch (SyntaxException e) { Assert.AreEqual(17, e.errorStartIndex); Assert.AreEqual(ruleString, e.ruleText); } }
public void ParsesRuleWithGlobalParametersMatch() { var ruleFromString = RuleParser.ParseToRule("A(x) -> B(x + stretch, stretch)", globalParameters: new string[] { "stretch" }); Assert.IsNull(ruleFromString.conditionalMatch); Assert.AreEqual("A(x)", ruleFromString.TargetSymbolString()); Assert.AreEqual(1, ruleFromString.replacementSymbols.Length); Assert.AreEqual('B', ruleFromString.replacementSymbols[0].targetSymbol); Assert.AreEqual(2, ruleFromString.replacementSymbols[0].evaluators.Length); Assert.AreEqual(12, ruleFromString.replacementSymbols[0].evaluators[0].DynamicInvoke(10, 2)); Assert.AreEqual(10, ruleFromString.replacementSymbols[0].evaluators[1].DynamicInvoke(10, 2)); }
public void RuleWith3ConsecutiveExpressionOperatorsThrowsMeaninfulException() { var ruleString = "A(x, y) -> B(x + / * y)"; try { RuleParser.ParseToRule(ruleString); } catch (SyntaxException e) { Assert.AreEqual(19, e.errorStartIndex); Assert.AreEqual(ruleString, e.ruleText); } }
public void ParsesRuleWithNonAlphaContextMatchWithParameter() { var ruleFromString = RuleParser.ParseToRule("C(x) < K(y) > `A(z) : x >= timeToFruit -> D(1)", globalParameters: new string[] { "timeToFruit" }); Assert.AreEqual(false, ruleFromString.conditionalMatch.DynamicInvoke(3, 0, 0, 0) > 0); Assert.AreEqual(false, ruleFromString.conditionalMatch.DynamicInvoke(3, 1, 0, 0) > 0); Assert.AreEqual(true, ruleFromString.conditionalMatch.DynamicInvoke(3, 4, 0, 0) > 0); Assert.AreEqual("C(x) < K(y) > `A(z)", ruleFromString.TargetSymbolString()); Assert.AreEqual(1, ruleFromString.replacementSymbols.Length); Assert.AreEqual('D', ruleFromString.replacementSymbols[0].targetSymbol); Assert.AreEqual(1, ruleFromString.replacementSymbols[0].evaluators.Length); Assert.AreEqual(1, ruleFromString.replacementSymbols[0].evaluators[0].DynamicInvoke(10, 10, 10, 10)); }
public void ParsesRuleWithExtraParens() { var ruleFromString = RuleParser.ParseToRule("A(x) -> A((x + 1))"); Assert.AreEqual(0, ruleFromString.forwardsMatch.Length); Assert.AreEqual(0, ruleFromString.backwardsMatch.Length); Assert.AreEqual("A(x)", ruleFromString.TargetSymbolString()); Assert.AreEqual(1, ruleFromString.replacementSymbols.Length); Assert.AreEqual('A', ruleFromString.replacementSymbols[0].targetSymbol); Assert.AreEqual(1, ruleFromString.replacementSymbols[0].evaluators.Length); Assert.AreEqual(2, ruleFromString.replacementSymbols[0].evaluators[0].DynamicInvoke(1)); Assert.AreEqual(11, ruleFromString.replacementSymbols[0].evaluators[0].DynamicInvoke(10)); }
public void RuleWithInvalidParameterInConditionalThrowsMeaningfulException() { var ruleString = "A(x, y) : x >= e -> B(x)"; try { RuleParser.ParseToRule(ruleString); } catch (SyntaxException e) { Assert.AreEqual(15, e.errorStartIndex); Assert.AreEqual(16, e.ErrorEndIndex); Assert.AreEqual(ruleString, e.ruleText); } }
public void RuleWithExtraRightParenThrowsMeaninfulException() { var ruleString = "A(x, y) -> B(x))"; try { RuleParser.ParseToRule(ruleString); } catch (SyntaxException e) { Assert.AreEqual(15, e.errorStartIndex); Assert.AreEqual(16, e.ErrorEndIndex); Assert.AreEqual(ruleString, e.ruleText); } }
public void RuleWithStrandedOperatorThrowsMeaninfulException() { var ruleString = "A(x, y) -> B(+)"; try { RuleParser.ParseToRule(ruleString); } catch (SyntaxException e) { Assert.AreEqual(13, e.errorStartIndex); Assert.AreEqual(14, e.ErrorEndIndex); Assert.AreEqual(ruleString, e.ruleText); } }
public void ParsesRuleWithParametersAndConditionalMatch() { var ruleFromString = RuleParser.ParseToRule("A(x, y): x < 10 -> A(x + 1, y - x)"); Assert.AreEqual(false, ruleFromString.conditionalMatch.DynamicInvoke(11, 2) > 0); Assert.AreEqual(false, ruleFromString.conditionalMatch.DynamicInvoke(10, 2) > 0); Assert.AreEqual(true, ruleFromString.conditionalMatch.DynamicInvoke(9, 202) > 0); Assert.AreEqual("A(x, y)", ruleFromString.TargetSymbolString()); Assert.AreEqual(1, ruleFromString.replacementSymbols.Length); Assert.AreEqual('A', ruleFromString.replacementSymbols[0].targetSymbol); Assert.AreEqual(2, ruleFromString.replacementSymbols[0].evaluators.Length); Assert.AreEqual(5, ruleFromString.replacementSymbols[0].evaluators[0].DynamicInvoke(4, 10)); Assert.AreEqual(6, ruleFromString.replacementSymbols[0].evaluators[1].DynamicInvoke(4, 10)); }
public void ParsesRuleWithFullContextParametersInOrder() { var ruleFromString = RuleParser.ParseToRule("C(x) < K(y) > A(z) -> D((timeToFruit - x) / (y -z))", globalParameters: new string[] { "timeToFruit" }); Assert.AreEqual("C(x) < K(y) > A(z)", ruleFromString.TargetSymbolString()); Assert.AreEqual(1, ruleFromString.replacementSymbols.Length); Assert.AreEqual('D', ruleFromString.replacementSymbols[0].targetSymbol); Assert.AreEqual(1, ruleFromString.replacementSymbols[0].evaluators.Length); var evaluatorFunction = ruleFromString.replacementSymbols[0].evaluators[0]; Assert.AreEqual((10.0f - 25.0f) / (4.0f - 8.0f), (float)evaluatorFunction.DynamicInvoke(10, 25, 4, 8), 1e-3f); Assert.AreEqual((11.2f - 892) / (6.66f - 1.7f), (float)evaluatorFunction.DynamicInvoke(11.2f, 892, 6.66f, 1.7f), 1e-3f); }
public void RuleWithMissingParameterThrowsMeaningfulException() { var ruleString = "A(x) -> B(x, yeet)"; try { RuleParser.ParseToRule(ruleString); } catch (SyntaxException e) { Assert.AreEqual(13, e.errorStartIndex); Assert.AreEqual(17, e.ErrorEndIndex); Assert.AreEqual(ruleString, e.ruleText); Assert.IsTrue(e.Message.Contains("\"yeet\""), "Should contain the missing parameter name"); } }
public void RuleWithProbabilityConditionalParses() { var ruleFromString = RuleParser.ParseToRule("P(0.5) | A(x) : x < global -> A(x + 1)", globalParameters: new string[] { "global" }); Assert.IsInstanceOf <ParsedStochasticRule>(ruleFromString); var stochastic = ruleFromString as ParsedStochasticRule; Assert.AreEqual(0.5, stochastic.probability); Assert.AreEqual("A(x)", stochastic.TargetSymbolString()); Assert.AreEqual(1, stochastic.replacementSymbols.Length); Assert.AreEqual('A', stochastic.replacementSymbols[0].targetSymbol); Assert.AreEqual(true, ruleFromString.conditionalMatch.DynamicInvoke(3, 2) > 0); Assert.AreEqual(true, ruleFromString.conditionalMatch.DynamicInvoke(2.5f, 2) > 0); Assert.AreEqual(false, ruleFromString.conditionalMatch.DynamicInvoke(2, 3) > 0); }
public void ParsesRuleWithEverySyntax() { var ruleFromString = RuleParser.ParseToRule("P(0.8 - (1/2)) | A < B > C(y) : y < global -> A", globalParameters: new string[] { "global" }); Assert.AreEqual(1, ruleFromString.forwardsMatch.Length); Assert.AreEqual(1, ruleFromString.backwardsMatch.Length); Assert.AreEqual("A < B > C(y)", ruleFromString.TargetSymbolString()); Assert.AreEqual("A", ruleFromString.ReplacementSymbolString()); Assert.IsInstanceOf <ParsedStochasticRule>(ruleFromString); var stochastic = ruleFromString as ParsedStochasticRule; Assert.AreEqual(0.3f, stochastic.probability, 1e-5); Assert.AreEqual(true, ruleFromString.conditionalMatch.DynamicInvoke(3, 2) > 0); Assert.AreEqual(true, ruleFromString.conditionalMatch.DynamicInvoke(2.5f, 2) > 0); Assert.AreEqual(false, ruleFromString.conditionalMatch.DynamicInvoke(2, 3) > 0); }
public void ParsesRuleWithParametersAndMultipleReplacementParameters() { var ruleFromString = RuleParser.ParseToRule("A(x, y) -> B(y + (y - x) * y)C(x)A(y, x)"); Assert.AreEqual("A(x, y)", ruleFromString.TargetSymbolString()); Assert.AreEqual(3, ruleFromString.replacementSymbols.Length); Assert.AreEqual('B', ruleFromString.replacementSymbols[0].targetSymbol); Assert.AreEqual(1, ruleFromString.replacementSymbols[0].evaluators.Length); Assert.AreEqual(4 + (4 - 30) * 4, ruleFromString.replacementSymbols[0].evaluators[0].DynamicInvoke(30, 4)); Assert.AreEqual('C', ruleFromString.replacementSymbols[1].targetSymbol); Assert.AreEqual(1, ruleFromString.replacementSymbols[1].evaluators.Length); Assert.AreEqual(30, ruleFromString.replacementSymbols[1].evaluators[0].DynamicInvoke(30, 4)); Assert.AreEqual('A', ruleFromString.replacementSymbols[2].targetSymbol); Assert.AreEqual(2, ruleFromString.replacementSymbols[2].evaluators.Length); Assert.AreEqual(4, ruleFromString.replacementSymbols[2].evaluators[0].DynamicInvoke(30, 4)); Assert.AreEqual(30, ruleFromString.replacementSymbols[2].evaluators[1].DynamicInvoke(30, 4)); }
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(); } }