From 38f7f8fa57cfe475f02159661a654b70d13b09d7 Mon Sep 17 00:00:00 2001 From: Robin Kahlow Date: Sun, 16 Jun 2019 02:33:22 +0100 Subject: [PATCH 1/5] removed pin concept, encode connections as 4-tuples, added tuple data algebra --- .../CSharpTranslatableGraphAlgebra.cs | 196 +++--------------- .../Algebras/DotExecutionGraphAlgebra.cs | 170 ++------------- .../Algebras/EvaluableGraphAlgebra.cs | 81 ++------ .../Algebras/TupleDataAlgebra.cs | 25 +++ .../ICSharpTranslatableInputDataPin.cs | 15 -- .../ICSharpTranslatableInputExecPin.cs | 12 -- .../ICSharpTranslatableNode.cs | 15 +- .../ICSharpTranslatableOutputDataPin.cs | 24 --- .../ICSharpTranslatableOutputExecPin.cs | 9 - .../Behaviors/DataGraph/IDataNode.cs | 22 -- .../Behaviors/DataGraph/IInputDataPin.cs | 7 - .../Behaviors/DataGraph/IOutputDataPin.cs | 7 - .../Behaviors/DotGraph/IDotNode.cs | 19 +- .../Behaviors/DotGraph/IDotOutputDataPin.cs | 13 -- .../Behaviors/DotGraph/IDotOutputExecPin.cs | 13 -- .../EvaluableGraph/IEvaluableInputDataPin.cs | 10 - .../EvaluableGraph/IEvaluableNode.cs | 12 +- .../EvaluableGraph/IEvaluableOutputDataPin.cs | 10 - .../ExecutionGraph/IExecutionNode.cs | 25 --- .../Behaviors/ExecutionGraph/IInputExecPin.cs | 6 - .../ExecutionGraph/IOutputExecPin.cs | 6 - ObjectAlgebraExecutionGraphs/Program.cs | 89 ++++---- .../Utility/NodeConnection.cs | 18 ++ .../Variants/IDataGraphAlgebra.cs | 9 +- .../Variants/IExecutionGraphAlgebra.cs | 9 +- 25 files changed, 156 insertions(+), 666 deletions(-) create mode 100644 ObjectAlgebraExecutionGraphs/Algebras/TupleDataAlgebra.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableInputDataPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableInputExecPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableOutputDataPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableOutputExecPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IDataNode.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IInputDataPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IOutputDataPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotOutputDataPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotOutputExecPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableInputDataPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableOutputDataPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IExecutionNode.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IInputExecPin.cs delete mode 100644 ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IOutputExecPin.cs create mode 100644 ObjectAlgebraExecutionGraphs/Utility/NodeConnection.cs diff --git a/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs index 4a1a6db..c395d88 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs @@ -3,95 +3,46 @@ using ObjectAlgebraExecutionGraphs.Variants; using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; -using System.Reflection; using System.Text; namespace ObjectAlgebraExecutionGraphs.Algebras { - public class CSharpTranslatableGraphAlgebra : IExecutionGraphAlgebra, ICSharpTranslatableOutputDataPin>, ICSharpTranslatableInputExecPin, ICSharpTranslatableOutputExecPin, ICSharpTranslatableInputDataPin, ICSharpTranslatableOutputDataPin> + public class CSharpTranslatableGraphAlgebra : IDataGraphAlgebra, IExecutionGraphAlgebra { - public ICSharpTranslatableNode, ICSharpTranslatableOutputDataPin> CreateLiteralNode(Type type, object value) - => new LiteralNode(type, value); - - public ICSharpTranslatableNode, ICSharpTranslatableOutputDataPin> CreateConcatenateNode(ICSharpTranslatableOutputDataPin aFrom, ICSharpTranslatableOutputDataPin bFrom, ICSharpTranslatableInputExecPin execTo) - => new ConcatenateNode(aFrom, bFrom, execTo); - - public ICSharpTranslatableNode, ICSharpTranslatableOutputDataPin> CreateReverseStringNode(ICSharpTranslatableOutputDataPin aFrom) - => new ReverseStringNode(aFrom); + public ICSharpTranslatableNode CreateConcatenateNode() => new ConcatenateNode(); + public ICSharpTranslatableNode CreateLiteralNode(Type type, object value) => new LiteralNode(type, value); + public ICSharpTranslatableNode CreateReverseStringNode() => new ReverseStringNode(); public Type TypeFromString(string typeString) => Type.GetType(typeString); - private class InputExecPin : ICSharpTranslatableInputExecPin - { - public string Label { get; } = RandomGenerator.GetRandomLowerLetters(16); - } - - private class OutputExecPin : ICSharpTranslatableOutputExecPin - { - - } - - private class InputDataPin : ICSharpTranslatableInputDataPin + public string TranslateImperative(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) { - public string VariableName { get; } = RandomGenerator.GetRandomLowerLetters(16); - public Type Type { get; } + StringBuilder builder = new StringBuilder(); - private readonly ICSharpTranslatableOutputDataPin incomingPin; - - public InputDataPin(Type type, ICSharpTranslatableOutputDataPin incomingPin) + foreach (var node in nodes) { - Type = type; - this.incomingPin = incomingPin; + builder.Append(node.TranslateVariables()); } - public IEnumerable TranslateCallPureFunction() + foreach (var node in nodes) { - if (incomingPin?.IsPure == true) - { - return incomingPin.TranslateCallPureFunction(); - } - - return new string[0]; + builder.Append(node.TranslatePureFunctions()); } - } - - private class OutputDataPin : ICSharpTranslatableOutputDataPin - { - public string VariableName { get; } = RandomGenerator.GetRandomLowerLetters(16); - public bool IsPure => node.IsPure; - public Type Type { get; } - private readonly ICSharpTranslatableNode, ICSharpTranslatableOutputDataPin> node; - - public OutputDataPin(ICSharpTranslatableNode, ICSharpTranslatableOutputDataPin> node, Type type) + foreach (var node in nodes) { - this.node = node; - Type = type; + builder.Append(node.TranslateStates()); } - public IEnumerable TranslateCallPureFunction() - { - if (!IsPure) - { - throw new Exception(); - } - - return node.TranslateCallPureFunction(); - } + return builder.ToString(); } - private abstract class BaseCSharpTranslatableNode : ICSharpTranslatableNode, ICSharpTranslatableOutputDataPin> + private abstract class BaseCSharpTranslatableNode : ICSharpTranslatableNode { - public IEnumerable InputExecPins => ixps; - public IEnumerable OutputExecPins => oxps; - public IEnumerable> InputDataPins => idps; - public IEnumerable> OutputDataPins => odps; - - protected readonly IList> idps = new List>(); - protected readonly IList> odps = new List>(); - protected readonly IList ixps = new List(); - protected readonly IList oxps = new List(); + public IImmutableList<(Type type, string variableName)> Inputs { get; private set; } = ImmutableList<(Type, string)>.Empty; + public IImmutableList<(Type type, string variableName)> Outputs { get; private set; } = ImmutableList<(Type, string)>.Empty; public virtual bool IsPure { get; } public string PureFunctionName { get; } @@ -102,80 +53,26 @@ public BaseCSharpTranslatableNode() PureFunctionName = $"{GetType().Name}_{nodeCounter++}"; } - public virtual string TranslateVariables() - { - return ""; - } + public virtual string TranslateVariables() => string.Concat(Inputs.Concat(Outputs).Select(x => $"{x.type} {x.variableName} = default({x.type});\n")); - public virtual string TranslatePureFunctions() - { - return ""; - } - - public virtual string TranslateStates() - { - return ""; - } - - public IEnumerable TranslateCallPureFunction() - { - var pureCalls = idps.SelectMany(idp => idp.TranslateCallPureFunction()); + public virtual string TranslatePureFunctions() => ""; - if (IsPure) - { - pureCalls = pureCalls.Concat(new[] { $"{PureFunctionName}();" }); - } + public virtual string TranslateStates() => ""; - return pureCalls.Distinct(); - } + protected void AddInput(Type type) => Inputs = Inputs.Add((type, RandomGenerator.GetRandomLowerLetters(8))); + protected void AddOutput(Type type) => Outputs = Outputs.Add((type, RandomGenerator.GetRandomLowerLetters(8))); } private class ConcatenateNode : BaseCSharpTranslatableNode { - private readonly ICSharpTranslatableInputExecPin execTo; - - public ConcatenateNode(ICSharpTranslatableOutputDataPin aFrom, ICSharpTranslatableOutputDataPin bFrom, ICSharpTranslatableInputExecPin execTo) - { - ixps.Add(new InputExecPin()); - idps.Add(new InputDataPin(typeof(string), aFrom)); - idps.Add(new InputDataPin(typeof(string), bFrom)); - odps.Add(new OutputDataPin(this, typeof(string))); - oxps.Add(new OutputExecPin()); - - this.execTo = execTo; - } - - public override string TranslateVariables() + public ConcatenateNode() { - return $"var {odps.Single().VariableName} = default(string);\n"; + AddInput(typeof(string)); + AddInput(typeof(string)); + AddOutput(typeof(string)); } - public override string TranslateStates() - { - StringBuilder builder = new StringBuilder(); - - // Translate label - builder.Append($"{ixps[0].Label}:\n"); - - // Translate pure calls - builder.Append(string.Join("\n", TranslateCallPureFunction())); - builder.Append("\n"); - - // Translate actual logic and result assignment - builder.Append($"{odps.Single().VariableName} = {idps[0].VariableName} + \" \" + {idps[1].VariableName};\n"); - - // Translate goto next - if (execTo != null) - { - builder.Append($"goto {execTo.Label};\n"); - } - else - { - builder.Append("return;\n"); - } - - return builder.ToString(); - } + public override string TranslateStates() => $"{Outputs.Single().variableName} = {Inputs[0].variableName} + \" \" + {Inputs[1].variableName};\n"; } private class LiteralNode : BaseCSharpTranslatableNode @@ -187,26 +84,13 @@ private class LiteralNode : BaseCSharpTranslatableNode public LiteralNode(Type type, object value) { this.value = value; - odps.Add(new OutputDataPin(this, type)); + AddOutput(type); } public override string TranslateVariables() { - var odp = OutputDataPins.Single(); - - return $"const {odp.Type.FullName} {odp.VariableName} = {value};\n"; - } - - public override string TranslatePureFunctions() - { - StringBuilder builder = new StringBuilder(); - - builder.Append($"void {PureFunctionName}()\n"); - builder.Append("{\n"); - //builder.Append($"{OutputDataPins.Single().VariableName} = {value};\n"); - builder.Append("}\n"); - - return builder.ToString(); + var output = Outputs.Single(); + return $"const {output.type.FullName} {output.variableName} = {value};\n"; } } @@ -214,27 +98,15 @@ private class ReverseStringNode : BaseCSharpTranslatableNode { public override bool IsPure => true; - public ReverseStringNode(ICSharpTranslatableOutputDataPin aFrom) + public ReverseStringNode() { - idps.Add(new InputDataPin(typeof(string), aFrom)); - odps.Add(new OutputDataPin(this, typeof(string))); - } - - public override string TranslateVariables() - { - return $"var {OutputDataPins.Single().VariableName} = default(string);\n"; + AddInput(typeof(string)); + AddOutput(typeof(string)); } public override string TranslatePureFunctions() { - StringBuilder builder = new StringBuilder(); - - builder.Append($"void {PureFunctionName}()\n"); - builder.Append("{\n"); - builder.Append($"{OutputDataPins.Single().VariableName} = string.Concat({idps.Single().VariableName}.Reverse());\n"); - builder.Append("}\n"); - - return builder.ToString(); + return $"{Outputs.Single().variableName} = string.Concat({Inputs.Single().variableName}.Reverse());\n"; } } } diff --git a/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs index 1dc1f75..68d8515 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs @@ -1,173 +1,33 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; -using ObjectAlgebraExecutionGraphs.Behaviors.DotGraph; -using ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph; +using ObjectAlgebraExecutionGraphs.Behaviors.DotGraph; +using ObjectAlgebraExecutionGraphs.Utility; using ObjectAlgebraExecutionGraphs.Variants; using System.Collections.Generic; +using System.Linq; using System.Text; namespace ObjectAlgebraExecutionGraphs.Algebras { - public class DotExecutionGraphAlgebra : IExecutionGraphAlgebra, IDotOutputDataPin>, IInputExecPin, IDotOutputExecPin, IInputDataPin, IDotOutputDataPin> + public class DotExecutionGraphAlgebra : IDataGraphAlgebra, IExecutionGraphAlgebra { - public IDotNode, IDotOutputDataPin> CreateLiteralNode(string type, object value) - => new LiteralNode(type, value); + private int nodeCounter; + private string MakeNodeName(string prefix) => $"{prefix}{nodeCounter++}"; - public IDotNode, IDotOutputDataPin> CreateConcatenateNode(IDotOutputDataPin aFrom, IDotOutputDataPin bFrom, IInputExecPin execTo) - => new ConcatenateNode(aFrom, bFrom, execTo); - - public IDotNode, IDotOutputDataPin> CreateReverseStringNode(IDotOutputDataPin aFrom) - => new ReverseStringNode(aFrom); + public IDotNode CreateConcatenateNode() => new DotNode(MakeNodeName("Concatenate")); + public IDotNode CreateLiteralNode(string type, object value) => new DotNode(MakeNodeName("Literal")); + public IDotNode CreateReverseStringNode() => new DotNode(MakeNodeName("ReverseString")); public string TypeFromString(string typeString) => typeString; - private class InputExecPin : IInputExecPin - { - } + public string TranslateImperative(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) + => $"digraph graph {{\n{string.Join("\n", dataConnections.Concat(execConnections).Distinct().Select(conn => $"{conn.FromNode.DotName} -> {conn.ToNode.DotName}"))}\n}}"; - private class OutputExecPin : IDotOutputExecPin + private class DotNode : IDotNode { - private IDotNode, IDotOutputDataPin> node; + public string DotName { get; } - public OutputExecPin(IDotNode, IDotOutputDataPin> node) + public DotNode(string name) { - this.node = node; - } - - public string GenerateDotGraph(string toName) => node.GenerateDotGraph(toName); - } - - private class InputDataPin : IInputDataPin - { - public string Type { get; } - - public InputDataPin(string type) - { - Type = type; - } - } - - private class OutputDataPin : IDotOutputDataPin - { - private IDotNode, IDotOutputDataPin> node; - - public OutputDataPin(IDotNode, IDotOutputDataPin> node, string type) - { - this.node = node; - Type = Type; - } - - public string Type { get; } - - public string GenerateDotGraph(string toName) => node.GenerateDotGraph(toName); - } - - private abstract class BaseNode : IDotNode, IDotOutputDataPin> - { - public string DotName => $"{GetType().Name}_{nodeId}"; - - private static int nodeCounter = 0; - private readonly int nodeId = nodeCounter++; - - public string GenerateDotGraph(string toName) - { - StringBuilder builder = new StringBuilder(); - - if (toName != null) - { - builder.AppendLine($"{DotName} -> {toName};"); - } - - builder.Append(GenerateIncomingDotGraph()); - - return builder.ToString(); - } - - protected abstract string GenerateIncomingDotGraph(); - - public IEnumerable InputExecPins => ixps; - public IEnumerable OutputExecPins => oxps; - public IEnumerable> InputDataPins => idps; - public IEnumerable> OutputDataPins => odps; - - protected readonly IList> idps = new List>(); - protected readonly IList> odps = new List>(); - protected readonly IList ixps = new List(); - protected readonly IList oxps = new List(); - } - - private class LiteralNode : BaseNode - { - private object value; - - public LiteralNode(string type, object value) - { - this.value = value; - odps.Add(new OutputDataPin(this, type)); - } - - protected override string GenerateIncomingDotGraph() - { - return ""; - } - } - - private class ConcatenateNode : BaseNode - { - private readonly IDotOutputDataPin aFrom; - private readonly IDotOutputDataPin bFrom; - private readonly IInputExecPin execTo; - - public ConcatenateNode(IDotOutputDataPin aFrom, IDotOutputDataPin bFrom, IInputExecPin execTo) - { - ixps.Add(new InputExecPin()); - odps.Add(new OutputDataPin(this, typeof(string).AssemblyQualifiedName)); - oxps.Add(new OutputExecPin(this)); - - this.aFrom = aFrom; - this.bFrom = bFrom; - this.execTo = execTo; - } - - protected override string GenerateIncomingDotGraph() - { - StringBuilder builder = new StringBuilder(); - - if (aFrom != null) - { - builder.Append(aFrom.GenerateDotGraph(DotName)); - } - - if (bFrom != null && aFrom != bFrom) - { - builder.Append(bFrom.GenerateDotGraph(DotName)); - } - - return builder.ToString(); - } - } - - private class ReverseStringNode : BaseNode - { - private IDotOutputDataPin aFrom; - - public ReverseStringNode(IDotOutputDataPin aFrom) - { - this.aFrom = aFrom; - - idps.Add(new InputDataPin(typeof(string).AssemblyQualifiedName)); - odps.Add(new OutputDataPin(this, typeof(string).AssemblyQualifiedName)); - } - - protected override string GenerateIncomingDotGraph() - { - StringBuilder builder = new StringBuilder(); - - if (aFrom != null) - { - builder.Append(aFrom.GenerateDotGraph(DotName)); - } - - return builder.ToString(); + DotName = name; } } } diff --git a/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs index 1d8bcce..07c1886 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs @@ -7,92 +7,39 @@ namespace ObjectAlgebraExecutionGraphs.Algebras { - public class EvaluableGraphAlgebra : IDataGraphAlgebra, IEvaluableInputDataPin, IEvaluableOutputDataPin> + public class EvaluableGraphAlgebra : IDataGraphAlgebra { - public IEvaluableNode CreateLiteralNode(Type type, object value) - => new LiteralNode(type, value); + public IEvaluableNode CreateLiteralNode(Type type, object value) => new LiteralNode(type, value); - public IEvaluableNode CreateReverseStringNode(IEvaluableOutputDataPin aFrom) - => new ReverseStringNode(aFrom); + public IEvaluableNode CreateReverseStringNode() => new ReverseStringNode(); public Type TypeFromString(string typeString) => Type.GetType(typeString); - private class InputDataPin : IEvaluableInputDataPin + private class LiteralNode : IEvaluableNode { - public Type Type { get; } - - private readonly IEvaluableOutputDataPin incomingOdp; - - public InputDataPin(Type type, IEvaluableOutputDataPin incomingOdp) - { - this.incomingOdp = incomingOdp; - Type = type; - } - - public object Evaluate() - { - return incomingOdp.Evaluate(); - } - } - - private class OutputDataPin : IEvaluableOutputDataPin - { - public Type Type { get; } - - private readonly IEvaluableNode node; - - public OutputDataPin(Type type, IEvaluableNode node) - { - this.node = node; - Type = type; - } - - public object Evaluate() - { - return node.Evaluate()[this]; - } - } - - private abstract class BaseNode : IEvaluableNode - { - public IEnumerable InputDataPins => idps; - public IEnumerable OutputDataPins => odps; - - protected readonly IList idps = new List(); - protected readonly IList odps = new List(); - - public abstract IReadOnlyDictionary Evaluate(); - } - - private class LiteralNode : BaseNode - { - private readonly Type type; private readonly object value; public LiteralNode(Type type, object value) { - this.type = type; this.value = value; - odps.Add(new OutputDataPin(type, this)); } - public override IReadOnlyDictionary Evaluate() + public IReadOnlyList Evaluate(IReadOnlyList inputs) { - return new Dictionary { [odps.Single()] = value }; + if (inputs.Count != 0) + { + throw new Exception(); + } + + return new[] { value }; } } - private class ReverseStringNode : BaseNode + private class ReverseStringNode : IEvaluableNode { - public ReverseStringNode(IEvaluableOutputDataPin aFrom) - { - idps.Add(new InputDataPin(typeof(string), aFrom)); - odps.Add(new OutputDataPin(typeof(string), this)); - } - - public override IReadOnlyDictionary Evaluate() + public IReadOnlyList Evaluate(IReadOnlyList inputs) { - return new Dictionary() { [odps.Single()] = string.Concat(((string)idps.Single().Evaluate()).Reverse()) }; + return new[] { string.Concat(inputs.Cast().Single().Reverse()) }; } } } diff --git a/ObjectAlgebraExecutionGraphs/Algebras/TupleDataAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/TupleDataAlgebra.cs new file mode 100644 index 0000000..8f06c21 --- /dev/null +++ b/ObjectAlgebraExecutionGraphs/Algebras/TupleDataAlgebra.cs @@ -0,0 +1,25 @@ +using ObjectAlgebraExecutionGraphs.Variants; + +namespace ObjectAlgebraExecutionGraphs.Algebras +{ + public class TupleDataAlgebra : IDataGraphAlgebra<(TType1, TType2), (TNode1, TNode2)> + { + private readonly IDataGraphAlgebra alg1; + private readonly IDataGraphAlgebra alg2; + + public TupleDataAlgebra(IDataGraphAlgebra algebra1, IDataGraphAlgebra algebra2) + { + alg1 = algebra1; + alg2 = algebra2; + } + + public (TNode1, TNode2) CreateLiteralNode((TType1, TType2) type, object value) + => (alg1.CreateLiteralNode(type.Item1, value), alg2.CreateLiteralNode(type.Item2, value)); + + public (TNode1, TNode2) CreateReverseStringNode() + => (alg1.CreateReverseStringNode(), alg2.CreateReverseStringNode()); + + public (TType1, TType2) TypeFromString(string typeString) + => (alg1.TypeFromString(typeString), alg2.TypeFromString(typeString)); + } +} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableInputDataPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableInputDataPin.cs deleted file mode 100644 index 8a3847d..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableInputDataPin.cs +++ /dev/null @@ -1,15 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; -using System.Collections.Generic; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.CSharpTranslatableGraph -{ - public interface ICSharpTranslatableInputDataPin : IInputDataPin - { - /// - /// Name of the pin's variable in code. - /// - string VariableName { get; } - - IEnumerable TranslateCallPureFunction(); - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableInputExecPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableInputExecPin.cs deleted file mode 100644 index dabf39d..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableInputExecPin.cs +++ /dev/null @@ -1,12 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.CSharpTranslatableGraph -{ - public interface ICSharpTranslatableInputExecPin : IInputExecPin - { - /// - /// Goto label of the input execution pin in code. - /// - string Label { get; } - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs index 13cf9e4..928d977 100644 --- a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs +++ b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs @@ -1,16 +1,11 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph; -using System.Collections.Generic; +using System.Collections.Generic; namespace ObjectAlgebraExecutionGraphs.Behaviors.CSharpTranslatableGraph { /// /// Node that is translatable to C#. /// - /// Input execution pin type - /// Output execution pin type - /// Input data pin type - /// Output data pin type - public interface ICSharpTranslatableNode : IExecutionNode + public interface ICSharpTranslatableNode { /// /// Translate all variables of this node to code. @@ -40,11 +35,5 @@ public interface ICSharpTranslatableNode : IExecutionNod /// Name of this node's local function if it is pure. /// public string PureFunctionName { get; } - - /// - /// Translates to code that calls this node's local function. - /// - /// Code for calling this node's local function. - public IEnumerable TranslateCallPureFunction(); } } diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableOutputDataPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableOutputDataPin.cs deleted file mode 100644 index 1dacb1b..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableOutputDataPin.cs +++ /dev/null @@ -1,24 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; -using System.Collections.Generic; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.CSharpTranslatableGraph -{ - public interface ICSharpTranslatableOutputDataPin : IOutputDataPin - { - /// - /// Name for the variable of this pin in code. - /// - string VariableName { get; } - - /// - /// Whether the node this pin is on is pure. - /// - bool IsPure { get; } - - /// - /// Proxy for translating to code for calling this pin's node's call to its local function. - /// - /// Code for calling this pin's node's call to its local function - IEnumerable TranslateCallPureFunction(); - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableOutputExecPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableOutputExecPin.cs deleted file mode 100644 index 7627a94..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableOutputExecPin.cs +++ /dev/null @@ -1,9 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.CSharpTranslatableGraph -{ - public interface ICSharpTranslatableOutputExecPin : IOutputExecPin - { - - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IDataNode.cs b/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IDataNode.cs deleted file mode 100644 index c5d797f..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IDataNode.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.DataGraph -{ - /// - /// A graph node holding a collection of pins. - /// - /// Input data pin type - /// Output data pin type - public interface IDataNode - { - /// - /// Input data pins of this node that can receive data. - /// - public IEnumerable InputDataPins { get; } - - /// - /// Output data pins of this node that can pass on data. - /// - public IEnumerable OutputDataPins { get; } - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IInputDataPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IInputDataPin.cs deleted file mode 100644 index bdf7db4..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IInputDataPin.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ObjectAlgebraExecutionGraphs.Behaviors.DataGraph -{ - public interface IInputDataPin - { - TType Type { get; } - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IOutputDataPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IOutputDataPin.cs deleted file mode 100644 index edcca5a..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/DataGraph/IOutputDataPin.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ObjectAlgebraExecutionGraphs.Behaviors.DataGraph -{ - public interface IOutputDataPin - { - TType Type { get; } - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotNode.cs b/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotNode.cs index 152ce4c..67e9db9 100644 --- a/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotNode.cs +++ b/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotNode.cs @@ -1,22 +1,7 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.DotGraph +namespace ObjectAlgebraExecutionGraphs.Behaviors.DotGraph { - /// - /// A graph node holding a collection of pins. Can create dot graphs for visualization. - /// - /// Input execution pin type - /// Output execution pin type - /// Input data pin type - /// Output data pin type - public interface IDotNode : IExecutionNode + public interface IDotNode { - /// - /// Generates a DOT graph for this node and its incoming nodes recursively. - /// - /// DOT graph for this node and its incoming nodes. - public string GenerateDotGraph(string toName); - /// /// Name of the node in the DOT graph. /// diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotOutputDataPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotOutputDataPin.cs deleted file mode 100644 index 7c87da9..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotOutputDataPin.cs +++ /dev/null @@ -1,13 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.DotGraph -{ - public interface IDotOutputDataPin : IOutputDataPin - { - /// - /// Generates a DOT graph for this pin's node and its incoming nodes recursively. - /// - /// DOT graph for this pin's node and its incoming nodes. - public string GenerateDotGraph(string toName); - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotOutputExecPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotOutputExecPin.cs deleted file mode 100644 index 9bf7de9..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/DotGraph/IDotOutputExecPin.cs +++ /dev/null @@ -1,13 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.DotGraph -{ - public interface IDotOutputExecPin : IOutputExecPin - { - /// - /// Generates a DOT graph for this pin's node and its incoming nodes recursively. - /// - /// DOT graph for this pin's node and its incoming nodes. - public string GenerateDotGraph(string toName); - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableInputDataPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableInputDataPin.cs deleted file mode 100644 index 996e764..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableInputDataPin.cs +++ /dev/null @@ -1,10 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; -using System; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.EvaluableGraph -{ - public interface IEvaluableInputDataPin : IInputDataPin - { - object Evaluate(); - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableNode.cs b/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableNode.cs index fe328d5..c2d3c07 100644 --- a/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableNode.cs +++ b/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableNode.cs @@ -1,15 +1,9 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; -using System.Collections.Generic; +using System.Collections.Generic; namespace ObjectAlgebraExecutionGraphs.Behaviors.EvaluableGraph { - /// - /// An evaluable graph node holding a collection of pins. - /// - /// Input data pin type - /// Output data pin type - public interface IEvaluableNode : IDataNode + public interface IEvaluableNode { - public IReadOnlyDictionary Evaluate(); + public IReadOnlyList Evaluate(IReadOnlyList inputs); } } diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableOutputDataPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableOutputDataPin.cs deleted file mode 100644 index 1742443..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableOutputDataPin.cs +++ /dev/null @@ -1,10 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; -using System; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.EvaluableGraph -{ - public interface IEvaluableOutputDataPin : IOutputDataPin - { - object Evaluate(); - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IExecutionNode.cs b/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IExecutionNode.cs deleted file mode 100644 index 4d356d7..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IExecutionNode.cs +++ /dev/null @@ -1,25 +0,0 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; -using System.Collections.Generic; - -namespace ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph -{ - /// - /// A graph node holding a collection of pins. - /// - /// Input execution pin type - /// Output execution pin type - /// Input data pin type - /// Output data pin type - public interface IExecutionNode : IDataNode - { - /// - /// Input execution pins of this node that can receive execution. - /// - public IEnumerable InputExecPins { get; } - - /// - /// Output execution pins of this node that can pass on execution. - /// - public IEnumerable OutputExecPins { get; } - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IInputExecPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IInputExecPin.cs deleted file mode 100644 index 3c2f96e..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IInputExecPin.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph -{ - public interface IInputExecPin - { - } -} diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IOutputExecPin.cs b/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IOutputExecPin.cs deleted file mode 100644 index a2b400c..0000000 --- a/ObjectAlgebraExecutionGraphs/Behaviors/ExecutionGraph/IOutputExecPin.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph -{ - public interface IOutputExecPin - { - } -} diff --git a/ObjectAlgebraExecutionGraphs/Program.cs b/ObjectAlgebraExecutionGraphs/Program.cs index cb10a66..51c069e 100644 --- a/ObjectAlgebraExecutionGraphs/Program.cs +++ b/ObjectAlgebraExecutionGraphs/Program.cs @@ -1,6 +1,8 @@ using ObjectAlgebraExecutionGraphs.Algebras; -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; -using ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph; +using ObjectAlgebraExecutionGraphs.Behaviors.CSharpTranslatableGraph; +using ObjectAlgebraExecutionGraphs.Behaviors.DotGraph; +using ObjectAlgebraExecutionGraphs.Behaviors.EvaluableGraph; +using ObjectAlgebraExecutionGraphs.Utility; using ObjectAlgebraExecutionGraphs.Variants; using System; using System.Collections.Generic; @@ -10,103 +12,82 @@ namespace ObjectAlgebraExecutionGraphs { internal static class Program { - private static IEnumerable CreateDataGraph(IDataGraphAlgebra factory) - where TNode : IDataNode + private static (IEnumerable nodes, IEnumerable> dataConnections) CreateDataGraph(TFactory factory) + where TFactory : IDataGraphAlgebra { var literalType = factory.TypeFromString(typeof(string).AssemblyQualifiedName); var literalNode = factory.CreateLiteralNode(literalType, "\"hello\""); - var reverseStringNode = factory.CreateReverseStringNode(literalNode.OutputDataPins.Single()); - var reverseStringNode2 = factory.CreateReverseStringNode(reverseStringNode.OutputDataPins.Single()); + var reverseStringNode = factory.CreateReverseStringNode(); + var reverseStringNode2 = factory.CreateReverseStringNode(); - return new[] { literalNode, reverseStringNode, reverseStringNode2 }; + var literalToReverse = new NodeConnection(literalNode, 0, reverseStringNode, 0); + var reverseToReverse2 = new NodeConnection(reverseStringNode, 0, reverseStringNode2, 0); + + return (new[] { literalNode, reverseStringNode, reverseStringNode2 }, new[] { literalToReverse, reverseToReverse2 }); } - private static IEnumerable CreateExecutionGraph(TIXP next, IExecutionGraphAlgebra factory) - where TNode : IExecutionNode + private static (IEnumerable nodes, IEnumerable> dataConnections, IReadOnlyList> execConnections) CreateExecutionGraph(TFactory factory) + where TFactory : IDataGraphAlgebra, IExecutionGraphAlgebra { var literalType = factory.TypeFromString(typeof(string).AssemblyQualifiedName); var literalNode = factory.CreateLiteralNode(literalType, "\"hello\""); - var reverseStringNode = factory.CreateReverseStringNode(literalNode.OutputDataPins.Single()); - var concatenateNode = factory.CreateConcatenateNode(literalNode.OutputDataPins.Single(), reverseStringNode.OutputDataPins.Single(), next); + var reverseStringNode = factory.CreateReverseStringNode(); + var concatenateNode = factory.CreateConcatenateNode(); + + var literalToReverse = new NodeConnection(literalNode, 0, reverseStringNode, 0); + var literalToConcatenate = new NodeConnection(literalNode, 0, concatenateNode, 0); + var reverseToConcatenate = new NodeConnection(reverseStringNode, 0, concatenateNode, 1); - return new[] { literalNode, reverseStringNode, concatenateNode }; + return (new[] { literalNode, reverseStringNode, concatenateNode }, new[] { literalToReverse, literalToConcatenate, reverseToConcatenate }, Array.Empty>()); } private static void RunExecutionGraphExamples() { // Generate a DOT graph from the an execution graph's last node var dotFactory = new DotExecutionGraphAlgebra(); - var dotExecutionGraph = CreateExecutionGraph(null, dotFactory); + var dotExecutionGraph = CreateExecutionGraph(dotFactory); Console.WriteLine("--- DOT graph ---"); - Console.WriteLine("digraph dotGraph {"); - Console.Write(dotExecutionGraph.Last().GenerateDotGraph(null)); - Console.WriteLine("}"); + Console.WriteLine(dotFactory.TranslateImperative(dotExecutionGraph.nodes, dotExecutionGraph.dataConnections, dotExecutionGraph.execConnections)); Console.WriteLine(); // Create the same execution graph, but now with elements translatable to C# var csharpTranslatableFactory = new CSharpTranslatableGraphAlgebra(); - var csharpTranslatableGraph = CreateExecutionGraph(null, csharpTranslatableFactory); + var csharpTranslatableGraph = CreateExecutionGraph(csharpTranslatableFactory); Console.WriteLine("--- C# translated graph ---"); - Console.WriteLine("void Func()"); - Console.WriteLine("{"); - foreach (var node in csharpTranslatableGraph) - { - Console.Write(node.TranslateVariables()); - } - foreach (var node in csharpTranslatableGraph) - { - Console.Write(node.TranslatePureFunctions()); - } - foreach (var node in csharpTranslatableGraph) - { - Console.Write(node.TranslateStates()); - } - Console.WriteLine("}"); + Console.WriteLine(csharpTranslatableFactory.TranslateImperative(csharpTranslatableGraph.nodes, csharpTranslatableGraph.dataConnections, csharpTranslatableGraph.execConnections)); } private static void RunDataGraphExamples() { // Create an evaluable data graph and evaluate it var evaluableFactory = new EvaluableGraphAlgebra(); - var evaluableDataGraph = CreateDataGraph(evaluableFactory); + (var evaluableNodes, var evaluableConnections) = CreateDataGraph(evaluableFactory); Console.Write("--- Evaluable graph ---"); Console.WriteLine("Last node outputs:"); - foreach ((var odp, var value) in evaluableDataGraph.Last().Evaluate()) + /*foreach ((var odp, var value) in evaluableNodes.Last().Evaluate() { Console.WriteLine(value); - } + }*/ // Generate a DOT graph from the same data graph's last node var dotFactory = new DotExecutionGraphAlgebra(); - var dotExecutionGraph = CreateDataGraph(dotFactory); + (var dotNodes, var dotConnections) = CreateDataGraph(dotFactory); Console.WriteLine("--- DOT graph ---"); - Console.WriteLine("digraph dotGraph {"); - Console.Write(dotExecutionGraph.Last().GenerateDotGraph(null)); - Console.WriteLine("}"); + Console.WriteLine(dotFactory.TranslateImperative(dotNodes, dotConnections, Array.Empty>())); Console.WriteLine(); // Create the same data graph, but now with elements translatable to C# var csharpTranslatableFactory = new CSharpTranslatableGraphAlgebra(); - var csharpTranslatableGraph = CreateDataGraph(csharpTranslatableFactory); + (var csharpNodes, var csharpConnections) = CreateDataGraph(csharpTranslatableFactory); Console.WriteLine("--- C# translated graph ---"); - Console.WriteLine("void Func()"); - Console.WriteLine("{"); - foreach (var node in csharpTranslatableGraph) - { - Console.Write(node.TranslateVariables()); - } - foreach (var node in csharpTranslatableGraph) - { - Console.Write(node.TranslatePureFunctions()); - } - - // Since we don't have any states, translate a call to the last pure node instead. - Console.WriteLine(string.Join("\n", csharpTranslatableGraph.Last().TranslateCallPureFunction().Distinct())); + Console.WriteLine(csharpTranslatableFactory.TranslateImperative(csharpNodes, csharpConnections, Array.Empty>())); - Console.WriteLine("}"); + // We can also combine two algebras + var tupleFactory = new TupleDataAlgebra(dotFactory, csharpTranslatableFactory); + var tupleGraph = CreateDataGraph<(string, Type), (IDotNode, ICSharpTranslatableNode), TupleDataAlgebra>(tupleFactory); } private static void Main() diff --git a/ObjectAlgebraExecutionGraphs/Utility/NodeConnection.cs b/ObjectAlgebraExecutionGraphs/Utility/NodeConnection.cs new file mode 100644 index 0000000..a7ee2e2 --- /dev/null +++ b/ObjectAlgebraExecutionGraphs/Utility/NodeConnection.cs @@ -0,0 +1,18 @@ +namespace ObjectAlgebraExecutionGraphs.Utility +{ + public struct NodeConnection + { + public TNode FromNode { get; } + public TNode ToNode { get; } + public int FromPinIndex { get; } + public int ToPinIndex { get; } + + public NodeConnection(TNode fromNode, int fromPinIndex, TNode toNode, int toPinIndex) + { + FromNode = fromNode; + FromPinIndex = fromPinIndex; + ToNode = toNode; + ToPinIndex = toPinIndex; + } + } +} diff --git a/ObjectAlgebraExecutionGraphs/Variants/IDataGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Variants/IDataGraphAlgebra.cs index 5984654..03b474a 100644 --- a/ObjectAlgebraExecutionGraphs/Variants/IDataGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Variants/IDataGraphAlgebra.cs @@ -1,12 +1,9 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.DataGraph; - -namespace ObjectAlgebraExecutionGraphs.Variants +namespace ObjectAlgebraExecutionGraphs.Variants { - public interface IDataGraphAlgebra - where TNode : IDataNode + public interface IDataGraphAlgebra { public TNode CreateLiteralNode(TType type, object value); - public TNode CreateReverseStringNode(TODP aFrom); + public TNode CreateReverseStringNode(); public TType TypeFromString(string typeString); } } diff --git a/ObjectAlgebraExecutionGraphs/Variants/IExecutionGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Variants/IExecutionGraphAlgebra.cs index 4d78fc0..5fea6df 100644 --- a/ObjectAlgebraExecutionGraphs/Variants/IExecutionGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Variants/IExecutionGraphAlgebra.cs @@ -1,10 +1,11 @@ -using ObjectAlgebraExecutionGraphs.Behaviors.ExecutionGraph; +using ObjectAlgebraExecutionGraphs.Utility; +using System.Collections.Generic; namespace ObjectAlgebraExecutionGraphs.Variants { - public interface IExecutionGraphAlgebra : IDataGraphAlgebra - where TNode : IExecutionNode + public interface IExecutionGraphAlgebra { - public TNode CreateConcatenateNode(TODP aFrom, TODP bFrom, TIXP execTo); + public TNode CreateConcatenateNode(); + public string TranslateImperative(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections); } } From a101a09118faa612db8b5dc0b3fb48dfc857bb39 Mon Sep 17 00:00:00 2001 From: Robin Kahlow Date: Sun, 16 Jun 2019 13:38:50 +0100 Subject: [PATCH 2/5] fixed pure node translation --- .../CSharpTranslatableGraphAlgebra.cs | 82 +++++++++++++++++-- .../ICSharpTranslatableNode.cs | 11 ++- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs index c395d88..f5e9466 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs @@ -17,6 +17,32 @@ public class CSharpTranslatableGraphAlgebra : IDataGraphAlgebra Type.GetType(typeString); + private static IEnumerable CallPureDependents(ICSharpTranslatableNode node, IEnumerable> dataConnections) + { + for (int toIndex = 0; toIndex < node.Inputs.Count; toIndex++) + { + var conns = dataConnections.Where(conn => conn.ToNode == node && conn.ToPinIndex == toIndex).ToArray(); + if (conns.Length > 1) + { + throw new Exception(); + } + + if (conns.Length == 1) + { + var conn = conns[0]; + if (conn.FromNode.IsPure) + { + foreach (var call in CallPureDependents(conn.FromNode, dataConnections)) + { + yield return call; + } + } + + yield return $"{conn.FromNode.PureFunctionName}();\n"; + } + } + } + public string TranslateImperative(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) { StringBuilder builder = new StringBuilder(); @@ -26,14 +52,33 @@ public string TranslateImperative(IEnumerable nodes, IE builder.Append(node.TranslateVariables()); } - foreach (var node in nodes) + foreach (var pureNode in nodes.Where(node => node.IsPure)) { - builder.Append(node.TranslatePureFunctions()); + builder.Append($"void {pureNode.PureFunctionName}()\n"); + builder.Append("{\n"); + builder.Append(pureNode.TranslatePureFunctions()); + builder.Append("}\n"); } - foreach (var node in nodes) + foreach (var stateNode in nodes.Where(node => !node.IsPure)) { - builder.Append(node.TranslateStates()); + IEnumerable pureCalls = CallPureDependents(stateNode, dataConnections); + + if (!stateNode.IsPure) + { + var outputConnectedLabels = new string[stateNode.ExecOutputCount]; + + var nodeExecConnections = execConnections + .Where(conn => conn.FromNode == stateNode) + .ToArray(); + + foreach (var execConn in nodeExecConnections) + { + outputConnectedLabels[execConn.FromPinIndex] = execConn.ToNode.ExecInputs[execConn.ToPinIndex]; + } + + builder.Append(stateNode.TranslateStates(outputConnectedLabels, string.Concat(pureCalls.Distinct()))); + } } return builder.ToString(); @@ -43,6 +88,8 @@ private abstract class BaseCSharpTranslatableNode : ICSharpTranslatableNode { public IImmutableList<(Type type, string variableName)> Inputs { get; private set; } = ImmutableList<(Type, string)>.Empty; public IImmutableList<(Type type, string variableName)> Outputs { get; private set; } = ImmutableList<(Type, string)>.Empty; + public IImmutableList ExecInputs { get; private set; } = ImmutableList.Empty; + public int ExecOutputCount { get; private set; } public virtual bool IsPure { get; } public string PureFunctionName { get; } @@ -57,10 +104,12 @@ public BaseCSharpTranslatableNode() public virtual string TranslatePureFunctions() => ""; - public virtual string TranslateStates() => ""; + public virtual string TranslateStates(IReadOnlyList outputExecLabels, string pureCalls) => ""; protected void AddInput(Type type) => Inputs = Inputs.Add((type, RandomGenerator.GetRandomLowerLetters(8))); protected void AddOutput(Type type) => Outputs = Outputs.Add((type, RandomGenerator.GetRandomLowerLetters(8))); + protected void AddExecInput() => ExecInputs = ExecInputs.Add(RandomGenerator.GetRandomLowerLetters(8)); + protected void AddExecOutput() => ExecOutputCount++; } private class ConcatenateNode : BaseCSharpTranslatableNode @@ -70,9 +119,30 @@ public ConcatenateNode() AddInput(typeof(string)); AddInput(typeof(string)); AddOutput(typeof(string)); + AddExecInput(); + AddExecOutput(); } - public override string TranslateStates() => $"{Outputs.Single().variableName} = {Inputs[0].variableName} + \" \" + {Inputs[1].variableName};\n"; + public override string TranslateStates(IReadOnlyList outputExecLabels, string pureCalls) + { + StringBuilder builder = new StringBuilder(); + + builder.Append($"{ExecInputs[0]}:\n"); + builder.Append(pureCalls); + builder.Append($"{Outputs.Single().variableName} = {Inputs[0].variableName} + \" \" + {Inputs[1].variableName};\n"); + + var outputLabel = outputExecLabels.Single(); + if (outputLabel != null) + { + builder.Append($"goto {outputLabel};\n"); + } + else + { + builder.Append("return;\n"); + } + + return builder.ToString(); + } } private class LiteralNode : BaseCSharpTranslatableNode diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs index 928d977..a0e7c92 100644 --- a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs +++ b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; namespace ObjectAlgebraExecutionGraphs.Behaviors.CSharpTranslatableGraph { @@ -7,6 +9,11 @@ namespace ObjectAlgebraExecutionGraphs.Behaviors.CSharpTranslatableGraph /// public interface ICSharpTranslatableNode { + public IImmutableList<(Type type, string variableName)> Inputs { get; } + public IImmutableList<(Type type, string variableName)> Outputs { get; } + public IImmutableList ExecInputs { get; } + public int ExecOutputCount { get; } + /// /// Translate all variables of this node to code. /// @@ -23,7 +30,7 @@ public interface ICSharpTranslatableNode /// Translate this node's stateful operations (ie. node with execution pins) into code. /// /// Code for the stateful operations of this node. - public string TranslateStates(); + public string TranslateStates(IReadOnlyList outputExecLabels, string pureCalls); /// /// Whether this node is pure (ie. has no execution pins of its own but is executed From 81df9cdd17c698dea6d5f01dad0eec2aa38e71d5 Mon Sep 17 00:00:00 2001 From: Robin Kahlow Date: Sun, 16 Jun 2019 13:39:31 +0100 Subject: [PATCH 3/5] remove / sort usings --- .../Algebras/DotExecutionGraphAlgebra.cs | 1 - ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs | 1 - ObjectAlgebraExecutionGraphs/Program.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs index 68d8515..b1c9868 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs @@ -3,7 +3,6 @@ using ObjectAlgebraExecutionGraphs.Variants; using System.Collections.Generic; using System.Linq; -using System.Text; namespace ObjectAlgebraExecutionGraphs.Algebras { diff --git a/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs index 07c1886..7c9540c 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; namespace ObjectAlgebraExecutionGraphs.Algebras { diff --git a/ObjectAlgebraExecutionGraphs/Program.cs b/ObjectAlgebraExecutionGraphs/Program.cs index 51c069e..841cd01 100644 --- a/ObjectAlgebraExecutionGraphs/Program.cs +++ b/ObjectAlgebraExecutionGraphs/Program.cs @@ -6,7 +6,6 @@ using ObjectAlgebraExecutionGraphs.Variants; using System; using System.Collections.Generic; -using System.Linq; namespace ObjectAlgebraExecutionGraphs { From 5dbc7733ff9c8ea51e7be873b7429e97a8e244c5 Mon Sep 17 00:00:00 2001 From: Robin Kahlow Date: Sun, 16 Jun 2019 14:44:55 +0100 Subject: [PATCH 4/5] moved translation functions from algebras to seperate functions --- .../CSharpTranslatableGraphAlgebra.cs | 67 ---------------- .../Algebras/DotExecutionGraphAlgebra.cs | 3 - ObjectAlgebraExecutionGraphs/Program.cs | 80 ++++++++++++++++++- .../Variants/IExecutionGraphAlgebra.cs | 1 - 4 files changed, 76 insertions(+), 75 deletions(-) diff --git a/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs index f5e9466..2c0751a 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs @@ -17,73 +17,6 @@ public class CSharpTranslatableGraphAlgebra : IDataGraphAlgebra Type.GetType(typeString); - private static IEnumerable CallPureDependents(ICSharpTranslatableNode node, IEnumerable> dataConnections) - { - for (int toIndex = 0; toIndex < node.Inputs.Count; toIndex++) - { - var conns = dataConnections.Where(conn => conn.ToNode == node && conn.ToPinIndex == toIndex).ToArray(); - if (conns.Length > 1) - { - throw new Exception(); - } - - if (conns.Length == 1) - { - var conn = conns[0]; - if (conn.FromNode.IsPure) - { - foreach (var call in CallPureDependents(conn.FromNode, dataConnections)) - { - yield return call; - } - } - - yield return $"{conn.FromNode.PureFunctionName}();\n"; - } - } - } - - public string TranslateImperative(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) - { - StringBuilder builder = new StringBuilder(); - - foreach (var node in nodes) - { - builder.Append(node.TranslateVariables()); - } - - foreach (var pureNode in nodes.Where(node => node.IsPure)) - { - builder.Append($"void {pureNode.PureFunctionName}()\n"); - builder.Append("{\n"); - builder.Append(pureNode.TranslatePureFunctions()); - builder.Append("}\n"); - } - - foreach (var stateNode in nodes.Where(node => !node.IsPure)) - { - IEnumerable pureCalls = CallPureDependents(stateNode, dataConnections); - - if (!stateNode.IsPure) - { - var outputConnectedLabels = new string[stateNode.ExecOutputCount]; - - var nodeExecConnections = execConnections - .Where(conn => conn.FromNode == stateNode) - .ToArray(); - - foreach (var execConn in nodeExecConnections) - { - outputConnectedLabels[execConn.FromPinIndex] = execConn.ToNode.ExecInputs[execConn.ToPinIndex]; - } - - builder.Append(stateNode.TranslateStates(outputConnectedLabels, string.Concat(pureCalls.Distinct()))); - } - } - - return builder.ToString(); - } - private abstract class BaseCSharpTranslatableNode : ICSharpTranslatableNode { public IImmutableList<(Type type, string variableName)> Inputs { get; private set; } = ImmutableList<(Type, string)>.Empty; diff --git a/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs index b1c9868..e0c69c2 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/DotExecutionGraphAlgebra.cs @@ -17,9 +17,6 @@ public class DotExecutionGraphAlgebra : IDataGraphAlgebra, IEx public string TypeFromString(string typeString) => typeString; - public string TranslateImperative(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) - => $"digraph graph {{\n{string.Join("\n", dataConnections.Concat(execConnections).Distinct().Select(conn => $"{conn.FromNode.DotName} -> {conn.ToNode.DotName}"))}\n}}"; - private class DotNode : IDotNode { public string DotName { get; } diff --git a/ObjectAlgebraExecutionGraphs/Program.cs b/ObjectAlgebraExecutionGraphs/Program.cs index 841cd01..5f1c010 100644 --- a/ObjectAlgebraExecutionGraphs/Program.cs +++ b/ObjectAlgebraExecutionGraphs/Program.cs @@ -6,6 +6,8 @@ using ObjectAlgebraExecutionGraphs.Variants; using System; using System.Collections.Generic; +using System.Linq; +using System.Text; namespace ObjectAlgebraExecutionGraphs { @@ -46,7 +48,7 @@ private static void RunExecutionGraphExamples() var dotFactory = new DotExecutionGraphAlgebra(); var dotExecutionGraph = CreateExecutionGraph(dotFactory); Console.WriteLine("--- DOT graph ---"); - Console.WriteLine(dotFactory.TranslateImperative(dotExecutionGraph.nodes, dotExecutionGraph.dataConnections, dotExecutionGraph.execConnections)); + Console.WriteLine(TranslateToDotGraph(dotExecutionGraph.nodes, dotExecutionGraph.dataConnections, dotExecutionGraph.execConnections)); Console.WriteLine(); // Create the same execution graph, but now with elements translatable to C# @@ -54,7 +56,7 @@ private static void RunExecutionGraphExamples() var csharpTranslatableGraph = CreateExecutionGraph(csharpTranslatableFactory); Console.WriteLine("--- C# translated graph ---"); - Console.WriteLine(csharpTranslatableFactory.TranslateImperative(csharpTranslatableGraph.nodes, csharpTranslatableGraph.dataConnections, csharpTranslatableGraph.execConnections)); + Console.WriteLine(TranslateToCSharp(csharpTranslatableGraph.nodes, csharpTranslatableGraph.dataConnections, csharpTranslatableGraph.execConnections)); } private static void RunDataGraphExamples() @@ -74,7 +76,7 @@ private static void RunDataGraphExamples() var dotFactory = new DotExecutionGraphAlgebra(); (var dotNodes, var dotConnections) = CreateDataGraph(dotFactory); Console.WriteLine("--- DOT graph ---"); - Console.WriteLine(dotFactory.TranslateImperative(dotNodes, dotConnections, Array.Empty>())); + Console.WriteLine(TranslateToDotGraph(dotNodes, dotConnections, Array.Empty>())); Console.WriteLine(); // Create the same data graph, but now with elements translatable to C# @@ -82,7 +84,7 @@ private static void RunDataGraphExamples() (var csharpNodes, var csharpConnections) = CreateDataGraph(csharpTranslatableFactory); Console.WriteLine("--- C# translated graph ---"); - Console.WriteLine(csharpTranslatableFactory.TranslateImperative(csharpNodes, csharpConnections, Array.Empty>())); + Console.WriteLine(TranslateToCSharp(csharpNodes, csharpConnections, Array.Empty>())); // We can also combine two algebras var tupleFactory = new TupleDataAlgebra(dotFactory, csharpTranslatableFactory); @@ -97,5 +99,75 @@ private static void Main() Console.WriteLine("### Execution graph examples ###"); RunExecutionGraphExamples(); } + + private static string TranslateToDotGraph(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) + => $"digraph graph {{\n{string.Join("\n", dataConnections.Concat(execConnections).Distinct().Select(conn => $"{conn.FromNode.DotName} -> {conn.ToNode.DotName}"))}\n}}"; + + private static IEnumerable CallPureDependents(ICSharpTranslatableNode node, IEnumerable> dataConnections) + { + for (int toIndex = 0; toIndex < node.Inputs.Count; toIndex++) + { + var conns = dataConnections.Where(conn => conn.ToNode == node && conn.ToPinIndex == toIndex).ToArray(); + if (conns.Length > 1) + { + throw new Exception(); + } + + if (conns.Length == 1) + { + var conn = conns[0]; + if (conn.FromNode.IsPure) + { + foreach (var call in CallPureDependents(conn.FromNode, dataConnections)) + { + yield return call; + } + } + + yield return $"{conn.FromNode.PureFunctionName}();\n"; + } + } + } + + private static string TranslateToCSharp(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) + { + StringBuilder builder = new StringBuilder(); + + foreach (var node in nodes) + { + builder.Append(node.TranslateVariables()); + } + + foreach (var pureNode in nodes.Where(node => node.IsPure)) + { + builder.Append($"void {pureNode.PureFunctionName}()\n"); + builder.Append("{\n"); + builder.Append(pureNode.TranslatePureFunctions()); + builder.Append("}\n"); + } + + foreach (var stateNode in nodes.Where(node => !node.IsPure)) + { + IEnumerable pureCalls = CallPureDependents(stateNode, dataConnections); + + if (!stateNode.IsPure) + { + var outputConnectedLabels = new string[stateNode.ExecOutputCount]; + + var nodeExecConnections = execConnections + .Where(conn => conn.FromNode == stateNode) + .ToArray(); + + foreach (var execConn in nodeExecConnections) + { + outputConnectedLabels[execConn.FromPinIndex] = execConn.ToNode.ExecInputs[execConn.ToPinIndex]; + } + + builder.Append(stateNode.TranslateStates(outputConnectedLabels, string.Concat(pureCalls.Distinct()))); + } + } + + return builder.ToString(); + } } } diff --git a/ObjectAlgebraExecutionGraphs/Variants/IExecutionGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Variants/IExecutionGraphAlgebra.cs index 5fea6df..73984f2 100644 --- a/ObjectAlgebraExecutionGraphs/Variants/IExecutionGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Variants/IExecutionGraphAlgebra.cs @@ -6,6 +6,5 @@ namespace ObjectAlgebraExecutionGraphs.Variants public interface IExecutionGraphAlgebra { public TNode CreateConcatenateNode(); - public string TranslateImperative(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections); } } From 21bb57c6f9a87ff0fabc5ae04dd3b50ac320b472 Mon Sep 17 00:00:00 2001 From: Robin Kahlow Date: Sun, 16 Jun 2019 15:09:01 +0100 Subject: [PATCH 5/5] use immutable collections everywhere --- .../CSharpTranslatableGraphAlgebra.cs | 4 ++-- .../Algebras/EvaluableGraphAlgebra.cs | 9 ++++---- .../ICSharpTranslatableNode.cs | 2 +- .../EvaluableGraph/IEvaluableNode.cs | 3 ++- ObjectAlgebraExecutionGraphs/Program.cs | 23 ++++++++++--------- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs index 2c0751a..6de3b61 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/CSharpTranslatableGraphAlgebra.cs @@ -37,7 +37,7 @@ public BaseCSharpTranslatableNode() public virtual string TranslatePureFunctions() => ""; - public virtual string TranslateStates(IReadOnlyList outputExecLabels, string pureCalls) => ""; + public virtual string TranslateStates(IImmutableList outputExecLabels, string pureCalls) => ""; protected void AddInput(Type type) => Inputs = Inputs.Add((type, RandomGenerator.GetRandomLowerLetters(8))); protected void AddOutput(Type type) => Outputs = Outputs.Add((type, RandomGenerator.GetRandomLowerLetters(8))); @@ -56,7 +56,7 @@ public ConcatenateNode() AddExecOutput(); } - public override string TranslateStates(IReadOnlyList outputExecLabels, string pureCalls) + public override string TranslateStates(IImmutableList outputExecLabels, string pureCalls) { StringBuilder builder = new StringBuilder(); diff --git a/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs b/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs index 7c9540c..8d4a900 100644 --- a/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs +++ b/ObjectAlgebraExecutionGraphs/Algebras/EvaluableGraphAlgebra.cs @@ -2,6 +2,7 @@ using ObjectAlgebraExecutionGraphs.Variants; using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; namespace ObjectAlgebraExecutionGraphs.Algebras @@ -23,22 +24,22 @@ public LiteralNode(Type type, object value) this.value = value; } - public IReadOnlyList Evaluate(IReadOnlyList inputs) + public IImmutableList Evaluate(IImmutableList inputs) { if (inputs.Count != 0) { throw new Exception(); } - return new[] { value }; + return ImmutableArray.Create(value); } } private class ReverseStringNode : IEvaluableNode { - public IReadOnlyList Evaluate(IReadOnlyList inputs) + public IImmutableList Evaluate(IImmutableList inputs) { - return new[] { string.Concat(inputs.Cast().Single().Reverse()) }; + return ImmutableArray.Create(string.Concat(inputs.Cast().Single().Reverse())); } } } diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs index a0e7c92..0910dd1 100644 --- a/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs +++ b/ObjectAlgebraExecutionGraphs/Behaviors/CSharpTranslatableGraph/ICSharpTranslatableNode.cs @@ -30,7 +30,7 @@ public interface ICSharpTranslatableNode /// Translate this node's stateful operations (ie. node with execution pins) into code. /// /// Code for the stateful operations of this node. - public string TranslateStates(IReadOnlyList outputExecLabels, string pureCalls); + public string TranslateStates(IImmutableList outputExecLabels, string pureCalls); /// /// Whether this node is pure (ie. has no execution pins of its own but is executed diff --git a/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableNode.cs b/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableNode.cs index c2d3c07..cdaf98f 100644 --- a/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableNode.cs +++ b/ObjectAlgebraExecutionGraphs/Behaviors/EvaluableGraph/IEvaluableNode.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; +using System.Collections.Immutable; namespace ObjectAlgebraExecutionGraphs.Behaviors.EvaluableGraph { public interface IEvaluableNode { - public IReadOnlyList Evaluate(IReadOnlyList inputs); + public IImmutableList Evaluate(IImmutableList inputs); } } diff --git a/ObjectAlgebraExecutionGraphs/Program.cs b/ObjectAlgebraExecutionGraphs/Program.cs index 5f1c010..c83f6f8 100644 --- a/ObjectAlgebraExecutionGraphs/Program.cs +++ b/ObjectAlgebraExecutionGraphs/Program.cs @@ -6,6 +6,7 @@ using ObjectAlgebraExecutionGraphs.Variants; using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Text; @@ -13,7 +14,7 @@ namespace ObjectAlgebraExecutionGraphs { internal static class Program { - private static (IEnumerable nodes, IEnumerable> dataConnections) CreateDataGraph(TFactory factory) + private static (IImmutableList nodes, IImmutableList> dataConnections) CreateDataGraph(TFactory factory) where TFactory : IDataGraphAlgebra { var literalType = factory.TypeFromString(typeof(string).AssemblyQualifiedName); @@ -24,10 +25,10 @@ private static (IEnumerable nodes, IEnumerable> dat var literalToReverse = new NodeConnection(literalNode, 0, reverseStringNode, 0); var reverseToReverse2 = new NodeConnection(reverseStringNode, 0, reverseStringNode2, 0); - return (new[] { literalNode, reverseStringNode, reverseStringNode2 }, new[] { literalToReverse, reverseToReverse2 }); + return (ImmutableArray.Create(literalNode, reverseStringNode, reverseStringNode2), ImmutableArray.Create(literalToReverse, reverseToReverse2)); } - private static (IEnumerable nodes, IEnumerable> dataConnections, IReadOnlyList> execConnections) CreateExecutionGraph(TFactory factory) + private static (IImmutableList nodes, IImmutableList> dataConnections, IImmutableList> execConnections) CreateExecutionGraph(TFactory factory) where TFactory : IDataGraphAlgebra, IExecutionGraphAlgebra { var literalType = factory.TypeFromString(typeof(string).AssemblyQualifiedName); @@ -39,7 +40,7 @@ private static (IEnumerable nodes, IEnumerable> dat var literalToConcatenate = new NodeConnection(literalNode, 0, concatenateNode, 0); var reverseToConcatenate = new NodeConnection(reverseStringNode, 0, concatenateNode, 1); - return (new[] { literalNode, reverseStringNode, concatenateNode }, new[] { literalToReverse, literalToConcatenate, reverseToConcatenate }, Array.Empty>()); + return (ImmutableArray.Create(literalNode, reverseStringNode, concatenateNode), ImmutableArray.Create(literalToReverse, literalToConcatenate, reverseToConcatenate), ImmutableArray>.Empty); } private static void RunExecutionGraphExamples() @@ -76,7 +77,7 @@ private static void RunDataGraphExamples() var dotFactory = new DotExecutionGraphAlgebra(); (var dotNodes, var dotConnections) = CreateDataGraph(dotFactory); Console.WriteLine("--- DOT graph ---"); - Console.WriteLine(TranslateToDotGraph(dotNodes, dotConnections, Array.Empty>())); + Console.WriteLine(TranslateToDotGraph(dotNodes, dotConnections, ImmutableArray>.Empty)); Console.WriteLine(); // Create the same data graph, but now with elements translatable to C# @@ -84,7 +85,7 @@ private static void RunDataGraphExamples() (var csharpNodes, var csharpConnections) = CreateDataGraph(csharpTranslatableFactory); Console.WriteLine("--- C# translated graph ---"); - Console.WriteLine(TranslateToCSharp(csharpNodes, csharpConnections, Array.Empty>())); + Console.WriteLine(TranslateToCSharp(csharpNodes, csharpConnections, ImmutableArray>.Empty)); // We can also combine two algebras var tupleFactory = new TupleDataAlgebra(dotFactory, csharpTranslatableFactory); @@ -100,10 +101,10 @@ private static void Main() RunExecutionGraphExamples(); } - private static string TranslateToDotGraph(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) + private static string TranslateToDotGraph(IImmutableList nodes, IImmutableList> dataConnections, IImmutableList> execConnections) => $"digraph graph {{\n{string.Join("\n", dataConnections.Concat(execConnections).Distinct().Select(conn => $"{conn.FromNode.DotName} -> {conn.ToNode.DotName}"))}\n}}"; - private static IEnumerable CallPureDependents(ICSharpTranslatableNode node, IEnumerable> dataConnections) + private static IEnumerable CallPureDependents(ICSharpTranslatableNode node, IImmutableList> dataConnections) { for (int toIndex = 0; toIndex < node.Inputs.Count; toIndex++) { @@ -129,7 +130,7 @@ private static IEnumerable CallPureDependents(ICSharpTranslatableNode no } } - private static string TranslateToCSharp(IEnumerable nodes, IEnumerable> dataConnections, IEnumerable> execConnections) + private static string TranslateToCSharp(IImmutableList nodes, IImmutableList> dataConnections, IImmutableList> execConnections) { StringBuilder builder = new StringBuilder(); @@ -148,7 +149,7 @@ private static string TranslateToCSharp(IEnumerable nod foreach (var stateNode in nodes.Where(node => !node.IsPure)) { - IEnumerable pureCalls = CallPureDependents(stateNode, dataConnections); + IImmutableList pureCalls = CallPureDependents(stateNode, dataConnections).ToImmutableArray(); if (!stateNode.IsPure) { @@ -163,7 +164,7 @@ private static string TranslateToCSharp(IEnumerable nod outputConnectedLabels[execConn.FromPinIndex] = execConn.ToNode.ExecInputs[execConn.ToPinIndex]; } - builder.Append(stateNode.TranslateStates(outputConnectedLabels, string.Concat(pureCalls.Distinct()))); + builder.Append(stateNode.TranslateStates(outputConnectedLabels.ToImmutableArray(), string.Concat(pureCalls.Distinct()))); } }