using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace ConsoleLSystem { public class LSystemNodeLiteral { public string name { get; } public int values_number { get; } public float[] values { get; set; } public LSystemNodeLiteral(string name, int values_number) { this.name = name; this.values_number = values_number; //in case it would be 0 values = new float[values_number]; } public LSystemNodeLiteral(LSystemNodeLiteral other) { this.name = other.name; this.values_number = other.values_number; //in case it would be 0 values = new float[this.values_number]; other.values.CopyTo(values, 0); } public static bool operator ==(LSystemNodeLiteral thisLiteral, LSystemNodeLiteral other) { return thisLiteral.name == other.name && thisLiteral.values_number == other.values_number; } public static bool operator !=(LSystemNodeLiteral thisLiteral, LSystemNodeLiteral other) { return !(thisLiteral.name == other.name && thisLiteral.values_number == other.values_number); } public override string ToString() { if (values_number == 0) { return name; } else { StringBuilder sb = new StringBuilder(name, name.Length + values_number * 7 + 4); sb.Append("("); for (int i = 0; i < values_number; i++) { var v = values[i]; sb.AppendFormat("{0:0.##}", v); if (i < values_number - 1) { sb.Append(","); } } sb.Append(")"); return sb.ToString(); } } } public class LSystemNode { public LSystemNodeLiteral literal { get; set; } public List children { get; set; } public LSystemNode mainChild { get; set; } private LSystemNode _parent; public LSystemNode parent { get { if (_parent is null) { return new LSystemNode(new LSystemNodeLiteral(" _ ", 0)); } else { return _parent; } } set { _parent = value; } } public LSystemNode(LSystemNodeLiteral nodeLiteral) { literal = nodeLiteral; children = new List(); mainChild = null; } public LSystemNode(LSystemNodeLiteral nodeLiteral, List children, LSystemNode mainChild) { literal = nodeLiteral; this.children = children; this.mainChild = mainChild; } public LSystemNode(LSystemNodeLiteral nodeLiteral, List children) { literal = nodeLiteral; this.children = children; this.mainChild = null; } public List getAllChildren() { var result = new List(children); if (mainChild != null){ result.Add(mainChild); } return result; } public LSystemNode deep_copy() { if (children.Count() == 0 && mainChild == null) { return new LSystemNode(new LSystemNodeLiteral(literal)); } else if (mainChild != null) { var result = new LSystemNode(new LSystemNodeLiteral(literal)); result.mainChild = mainChild.deep_copy(); return result; } else { var new_children = new List(); foreach (var x in children) { new_children.Add(x.deep_copy()); } return new LSystemNode(literal, new_children, this.mainChild.deep_copy()); } } private static LSystemNode deepestNode(LSystemNode node) { while (node.mainChild != null) { node = node.mainChild; } return node; } public LSystemNode newParent() { return deepestNode(this); } public override string ToString() { StringBuilder sb = new StringBuilder(literal.ToString()); var node = this; while (true) { foreach (var child in node.children) { sb.Append("["); sb.Append(child.ToString()); sb.Append("]"); } if (node.mainChild != null) { sb.Append(node.mainChild.literal.ToString()); node = node.mainChild; } else { return sb.ToString(); } } } } public class LSystemEvaluator { public LSystemNode lSystemString { get; set; } public List lSystemRules { get; set; } public String[] ignored { get; set; } public LSystemEvaluator(LSystemNode startingString, List rules) { lSystemString = startingString; lSystemRules = rules; ignored = new String[0]; } public LSystemEvaluator(LSystemNode startingString, List rules, String[] ignored) { lSystemString = startingString; lSystemRules = rules; this.ignored = ignored; } private LSystemNode _rewrite(LSystemNode node) { foreach (var rule in lSystemRules) { if (rule.is_aplicable(node, ignored)) { return rule.rewrite(node, ignored); } } return new LSystemNode(node.literal); } //private void _rewrite_recursive(LSystemNode node, LSystemNode parent) { // var new_node = _rewrite(node); // parent.children.Add(new_node); // new_node.parent = parent; // var new_parent = new_node.newParent(); // foreach (var child in node.children) { // _rewrite_recursive(child, new_parent); // } //} private void _rewrite_recursive(LSystemNode node, LSystemNode parent) { var new_node = _rewrite(node); parent.children.Add(new_node); new_node.parent = parent; var new_parent = new_node.newParent(); foreach (var child in node.children) { _rewrite_recursive(child, new_parent); } while (node.mainChild != null) { new_node = _rewrite(node.mainChild); new_node.parent = new_parent; new_parent.mainChild = new_node; new_parent = new_node.newParent(); foreach (var child in node.mainChild.children) { _rewrite_recursive(child, new_parent); } node = node.mainChild; } } public void rewrite() { var new_root = _rewrite(lSystemString); var new_parent = new_root.newParent(); foreach (var child in lSystemString.children) { _rewrite_recursive(child, new_parent); } var node = lSystemString; while (node.mainChild != null) { var new_node = _rewrite(node.mainChild); new_node.parent = new_parent; new_parent.mainChild = new_node; new_parent = new_node.newParent(); foreach (var child in node.mainChild.children) { _rewrite_recursive(child, new_parent); } node = node.mainChild; } lSystemString = new_root; } //private void rewrite(ref LSystemNode currentNode) } //abstract class LSystemWordParser { } //abstract class LSystemRulesParser { } class A { public int B { get; set; } public A[] AA { get; set; } } class Program { static void runParametric() { Dictionary variableIndex = new Dictionary { {"a", 0}, {"b", 1}, }; var predecesor1 = LSystemFileParser.parseContextLiteral("B(a,b)"); var predecesor2 = LSystemFileParser.parseContextLiteral("A(a)"); var condition1 = MathExpressionComparasionParser.parse(variableIndex, "a>b"); var condition2 = MathExpressionComparasionParser.parse(variableIndex, "a>5"); var builder = new LSystemWordGeneratorBuilder(variableIndex); var consequent1 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(0,b)[A(a/2)]A(a/2)", builder); var consequent2 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(a+3.5,b+1)", builder); var consequent3 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(0,a)", builder); var consequent4 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(a+1)", builder); var rule1 = new LSystemRuleParametric(predecesor1, new MathExpressionComparison[] { condition1 }, consequent1 ); var rule2 = new LSystemRuleParametric(predecesor1, new MathExpressionComparison[] { }, consequent2 ); var rule3 = new LSystemRuleParametric(predecesor2, new MathExpressionComparison[] { condition2 }, consequent3 ); var rule4 = new LSystemRuleParametric(predecesor2, new MathExpressionComparison[] { }, consequent4); var axiom = LSystemFileParser.parseWord("A(6)", new LSystemWordBuilder()); var rules = new List { rule1, rule2, rule3, rule4 }; var evaluator = new LSystemEvaluator(axiom, rules); Console.WriteLine(evaluator.lSystemString.ToString()); for (int i = 0; i < 20; i++) { evaluator.rewrite(); Console.WriteLine(evaluator.lSystemString.ToString()); } } static void runContext() { var axiom = LSystemFileParser.parseWord("A(1)A(1)A(1)A(1)A(1)A(1)B(2)", new LSystemWordBuilder()); var predecesor = LSystemFileParser.parseContextLiteral("A(a)"); var predecesor1 = LSystemFileParser.parseContextLiteral("B(b)"); var contex = new LSystemContext(); contex.setOnlySucceeding(new LSystemNodeLiteral[] { new LSystemNodeLiteral("B", 1) }); var contex1 = new LSystemContext(); contex1.setOnlyPreceding(new LSystemNodeLiteral("A", 1)); Dictionary variableIndex = new Dictionary { { "a", 0 }, { "b", 1 }, }; var builder = new LSystemWordGeneratorBuilder(variableIndex); var consequent = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(a)", builder); var consequent1 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(1)", builder); var consequent2 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(a+1)", builder); MathExpressionComparison comparison = MathExpressionComparasionParser.parse(variableIndex, "a>b"); MathExpressionComparison comparison1 = MathExpressionComparasionParser.parse(variableIndex, "a<=b"); var rule = new LSystemRuleParametricStochasticContext(predecesor, new MathExpressionComparison[] { comparison }, consequent, contex); var rule1 = new LSystemRuleParametricStochasticContext(predecesor, new MathExpressionComparison[] { }, consequent2, contex); var rule2 = new LSystemRuleParametricStochasticContext(predecesor1, new MathExpressionComparison[] { comparison }, consequent1, contex1); var rules = new List { rule, rule1, rule2 }; var evaluator = new LSystemEvaluator(axiom, rules); Console.WriteLine(evaluator.lSystemString.ToString()); for (int i = 0; i < 20; i++) { evaluator.rewrite(); Console.WriteLine(evaluator.lSystemString.ToString()); } } static void runFile() { Console.WriteLine("Enter filepath:"); string filepath = Console.ReadLine(); var evaluator = LSystemFileParser.parseLSystem(new StreamReader(filepath)); Console.WriteLine(evaluator.lSystemString.ToString()); while (true) { Console.ReadLine(); evaluator.rewrite(); Console.WriteLine(evaluator.lSystemString.ToString()); } } static void Main(string[] args) { runFile(); //runContext(); //var Al = new LSystemNodeLiteral("Al", 0); //var Ar = new LSystemNodeLiteral("Ar", 0); //var Bl = new LSystemNodeLiteral("Bl", 0); //var Br = new LSystemNodeLiteral("Br", 0); //var root = new LSystemNode(Ar); //var rule_list = new List(); //var result = new LSystemNode(Al); //result.children.Add(new LSystemNode(Br)); //rule_list.Add(new LSystemRuleBasic(Ar, result)); //result = new LSystemNode(Bl); //result.children.Add(new LSystemNode(Ar)); //rule_list.Add(new LSystemRuleBasic(Al, result)); //result = new LSystemNode(Ar); //rule_list.Add(new LSystemRuleBasic(Br, result)); //result = new LSystemNode(Al); //rule_list.Add(new LSystemRuleBasic(Bl, result)); //var evaluator = new LSystemEvaluator(root, rule_list); //for (int i=0; i < 5; i++) { // Console.WriteLine(evaluator.lSystemString.ToString()); // evaluator.rewrite(); //} //Console.WriteLine(evaluator.lSystemString.ToString()); //var node = LSystemFileParser.parseWord("A[AA][A]AB(1,2)[A(1)]C", new LSystemWordBuilder()); //Console.WriteLine(node.ToString()); } } }