Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
LeftDivide.cs
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
9
11{
15 public class LeftDivide : BinaryOperator
16 {
26 : base(Left, Right, Start, Length, Expression)
27 {
28 }
29
36 {
37 IElement Left = this.left.Evaluate(Variables);
38 IElement Right = this.right.Evaluate(Variables);
39
40 return EvaluateDivision(Left, Right, this);
41 }
42
48 public override async Task<IElement> EvaluateAsync(Variables Variables)
49 {
50 if (!this.isAsync)
51 return this.Evaluate(Variables);
52
53 IElement Left = await this.left.EvaluateAsync(Variables);
54 IElement Right = await this.right.EvaluateAsync(Variables);
55
56 return EvaluateDivision(Left, Right, this);
57 }
58
66 public static IElement EvaluateDivision(IElement Left, IElement Right, ScriptNode Node)
67 {
68 IElement Result;
69 IRingElement Temp;
70
71 if (Left is IRingElement LE && Right is IRingElement RE)
72 {
73 // TODO: Optimize in case of matrices. It's more efficient to employ a solve algorithm than to compute the inverse and the multiply.
74
75 Temp = LE.Invert();
76 if (!(Temp is null))
77 {
78 Result = RE.MultiplyLeft(Temp);
79 if (!(Result is null))
80 return Result;
81
82 Result = Temp.MultiplyRight(RE);
83 if (!(Result is null))
84 return Result;
85 }
86 }
87
88 if (Left.IsScalar)
89 {
90 if (Right.IsScalar)
91 {
92 ISet LeftSet = Left.AssociatedSet;
93 ISet RightSet = Right.AssociatedSet;
94
95 if (!LeftSet.Equals(RightSet))
96 {
97 if (Expression.UpgradeField(ref Left, ref LeftSet, ref Right, ref RightSet))
98 {
99 LE = Left as IRingElement;
100 RE = Right as IRingElement;
101 if (!(LE is null) && !(RE is null))
102 {
103 Temp = LE.Invert();
104 if (!(Temp is null))
105 {
106 Result = RE.MultiplyLeft(Temp);
107 if (!(Result is null))
108 return Result;
109
110 Result = Temp.MultiplyRight(RE);
111 if (!(Result is null))
112 return Result;
113 }
114 }
115 }
116 }
117
118 Result = EvaluateNamedOperator("op_Division", Left, Right, Node);
119 if (!(Result is null))
120 return Result;
121
122 throw new ScriptRuntimeException("Operands cannot be divided.", Node);
123 }
124 else
125 {
126 LinkedList<IElement> Elements = new LinkedList<IElement>();
127
128 foreach (IElement RightChild in Right.ChildElements)
129 Elements.AddLast(EvaluateDivision(Left, RightChild, Node));
130
131 return Right.Encapsulate(Elements, Node);
132 }
133 }
134 else
135 {
136 if (Right.IsScalar)
137 {
138 LinkedList<IElement> Elements = new LinkedList<IElement>();
139
140 foreach (IElement LeftChild in Left.ChildElements)
141 Elements.AddLast(EvaluateDivision(LeftChild, Right, Node));
142
143 return Left.Encapsulate(Elements, Node);
144 }
145 else
146 {
147 if (Left is ISet Set1 && Right is ISet Set2)
148 return new SetDifference(Set1, Set2);
149 else
150 {
151 ICollection<IElement> LeftChildren = Left.ChildElements;
152 ICollection<IElement> RightChildren = Right.ChildElements;
153
154 if (LeftChildren.Count == RightChildren.Count)
155 {
156 LinkedList<IElement> Elements = new LinkedList<IElement>();
157 IEnumerator<IElement> eLeft = LeftChildren.GetEnumerator();
158 IEnumerator<IElement> eRight = RightChildren.GetEnumerator();
159
160 try
161 {
162 while (eLeft.MoveNext() && eRight.MoveNext())
163 Elements.AddLast(EvaluateDivision(eLeft.Current, eRight.Current, Node));
164 }
165 finally
166 {
167 eLeft.Dispose();
168 eRight.Dispose();
169 }
170
171 return Left.Encapsulate(Elements, Node);
172 }
173 else
174 {
175 LinkedList<IElement> LeftResult = new LinkedList<IElement>();
176
177 foreach (IElement LeftChild in LeftChildren)
178 {
179 LinkedList<IElement> RightResult = new LinkedList<IElement>();
180
181 foreach (IElement RightChild in RightChildren)
182 RightResult.AddLast(EvaluateDivision(LeftChild, RightChild, Node));
183
184 LeftResult.AddLast(Right.Encapsulate(RightResult, Node));
185 }
186
187 return Left.Encapsulate(LeftResult, Node);
188 }
189 }
190 }
191 }
192 }
193
194 }
195}
Class managing a script expression.
Definition: Expression.cs:39
static bool UpgradeField(ref IElement E1, ref ISet Set1, ref IElement E2, ref ISet Set2)
Upgrades elements if necessary, to a common field extension, trying to make them compatible.
Definition: Expression.cs:5070
Base class for all binary operators.
ScriptNode right
Right operand.
ScriptNode left
Left operand.
static IElement EvaluateNamedOperator(string Name, IElement Left, IElement Right, ScriptNode Node)
Evaluates a named operator available in code-behind.
bool isAsync
If subtree is asynchroneous.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
abstract IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
virtual Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
Definition: ScriptNode.cs:158
Represents a set difference A\B.
override async Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
Definition: LeftDivide.cs:48
override IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
Definition: LeftDivide.cs:35
static IElement EvaluateDivision(IElement Left, IElement Right, ScriptNode Node)
Divides the left operand from the right one.
Definition: LeftDivide.cs:66
LeftDivide(ScriptNode Left, ScriptNode Right, int Start, int Length, Expression Expression)
Left-Division operator.
Definition: LeftDivide.cs:25
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:20
ICollection< IElement > ChildElements
An enumeration of child elements. If the element is a scalar, this property will return null.
Definition: IElement.cs:49
IElement Encapsulate(ICollection< IElement > Elements, ScriptNode Node)
Encapsulates a set of elements into a similar structure as that provided by the current element.
bool IsScalar
If the element represents a scalar value.
Definition: IElement.cs:41
Basic interface for all types of ring elements.
Definition: IRingElement.cs:10
IRingElement MultiplyRight(IRingElement Element)
Tries to multiply an element to the current element, from the right.
IRingElement Invert()
Inverts the element, if possible.
Basic interface for all types of sets.
Definition: ISet.cs:10