Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
FunctionTwoScalarVariables.cs
2using System.Numerics;
3using System.Threading.Tasks;
9
10namespace Waher.Script.Model
11{
16 {
27 {
28 }
29
33 public abstract bool UpgradeScalarsToSameSet { get; }
34
43 {
44 if (Argument1.IsScalar)
45 {
46 if (Argument2.IsScalar)
47 {
48 ISet Set1 = Argument1.AssociatedSet;
49 ISet Set2 = Argument2.AssociatedSet;
50
51 if (Set1 != Set2)
52 {
53 if (!this.UpgradeScalarsToSameSet ||
54 !Expression.UpgradeField(ref Argument1, ref Set1, ref Argument2, ref Set2))
55 {
56 return this.EvaluateScalar(Argument1, Argument2, Variables);
57 }
58 }
59
60 object x = Argument1.AssociatedObjectValue;
61 object y = Argument2.AssociatedObjectValue;
62
63 if (x is double xd && y is double yd)
64 return this.EvaluateScalar(xd, yd, Variables);
65
66 if (x is Complex xz && y is Complex yz)
67 return this.EvaluateScalar(xz, yz, Variables);
68
69 if (x is bool xb && y is bool yb)
70 return this.EvaluateScalar(xb, yb, Variables);
71
72 if (x is string xs && y is string ys)
73 return this.EvaluateScalar(xs, ys, Variables);
74
75 double arg1, arg2;
76
77 if (x is double xd2)
78 arg1 = xd2;
79 else
80 {
81 if (x is IPhysicalQuantity Q1)
82 arg1 = Q1.ToPhysicalQuantity().Magnitude;
83 else
84 return this.EvaluateScalar(Argument1, Argument2, Variables);
85 }
86
87 if (y is double yd2)
88 arg2 = yd2;
89 else
90 {
91 if (y is IPhysicalQuantity Q2)
92 arg2 = Q2.ToPhysicalQuantity().Magnitude;
93 else
94 return this.EvaluateScalar(Argument1, Argument2, Variables);
95 }
96
97 return this.EvaluateScalar(arg1, arg2, Variables);
98 }
99 else
100 {
102
103 foreach (IElement E in Argument2.ChildElements)
104 Elements.Add(this.Evaluate(Argument1, E, Variables));
105
106 return Argument2.Encapsulate(Elements, this);
107 }
108 }
109 else
110 {
111 if (Argument2.IsScalar)
112 {
114
115 foreach (IElement E in Argument1.ChildElements)
116 Elements.Add(this.Evaluate(E, Argument2, Variables));
117
118 return Argument1.Encapsulate(Elements, this);
119 }
120 else
121 {
122 ICollection<IElement> Argument1Children = Argument1.ChildElements;
123 ICollection<IElement> Argument2Children = Argument2.ChildElements;
124
125 if (Argument1Children.Count == Argument2Children.Count)
126 {
128 IEnumerator<IElement> eArgument1 = Argument1Children.GetEnumerator();
129 IEnumerator<IElement> eArgument2 = Argument2Children.GetEnumerator();
130
131 try
132 {
133 while (eArgument1.MoveNext() && eArgument2.MoveNext())
134 Elements.Add(this.Evaluate(eArgument1.Current, eArgument2.Current, Variables));
135 }
136 finally
137 {
138 eArgument1.Dispose();
139 eArgument2.Dispose();
140 }
141
142 return Argument1.Encapsulate(Elements, this);
143 }
144 else
145 {
146 ChunkedList<IElement> Argument1Result = new ChunkedList<IElement>();
147
148 foreach (IElement Argument1Child in Argument1Children)
149 {
150 ChunkedList<IElement> Argument2Result = new ChunkedList<IElement>();
151
152 foreach (IElement Argument2Child in Argument2Children)
153 Argument2Result.Add(this.Evaluate(Argument1Child, Argument2Child, Variables));
154
155 Argument1Result.Add(Argument2.Encapsulate(Argument2Result, this));
156 }
157
158 return Argument1.Encapsulate(Argument1Result, this);
159 }
160 }
161 }
162 }
163
172 {
173 object v1 = Argument1.AssociatedObjectValue;
174 object v2 = Argument2.AssociatedObjectValue;
175
176 if (Expression.TryConvert(v1, out string s1) && Expression.TryConvert(v2, out string s2))
177 return this.EvaluateScalar(s1, s2, Variables);
178 else if (Expression.TryConvert(v1, out double d1) && Expression.TryConvert(v2, out double d2))
179 return this.EvaluateScalar(d1, d2, Variables);
180 else if (Expression.TryConvert(v1, out bool b1) && Expression.TryConvert(v2, out bool b2))
181 return this.EvaluateScalar(b1, b2, Variables);
182 else if (Expression.TryConvert(v1, out Complex z1) && Expression.TryConvert(v2, out Complex z2))
183 return this.EvaluateScalar(z1, z2, Variables);
184 else if (Expression.TryConvert(v1, out Integer i1) && Expression.TryConvert(v2, out Integer i2))
185 return this.EvaluateScalar((double)i1.Value, (double)i2.Value, Variables);
186 else if (Expression.TryConvert(v1, out RationalNumber q1) && Expression.TryConvert(v2, out RationalNumber q2))
187 return this.EvaluateScalar(q1.ToDouble(), q2.ToDouble(), Variables);
188 else
189 throw new ScriptRuntimeException("Type of scalar not supported.", this);
190 }
191
200 {
201 throw new ScriptRuntimeException("Double-valued arguments not supported.", this);
202 }
203
212 {
213 throw new ScriptRuntimeException("Complex-valued arguments not supported.", this);
214 }
215
224 {
225 throw new ScriptRuntimeException("Boolean-valued arguments not supported.", this);
226 }
227
236 {
237 throw new ScriptRuntimeException("String-valued arguments not supported.", this);
238 }
239
247 public override async Task<IElement> EvaluateAsync(IElement Argument1, IElement Argument2, Variables Variables)
248 {
249 if (Argument1.IsScalar)
250 {
251 if (Argument2.IsScalar)
252 {
253 ISet Set1 = Argument1.AssociatedSet;
254 ISet Set2 = Argument2.AssociatedSet;
255
256 if (Set1 != Set2)
257 {
258 if (!this.UpgradeScalarsToSameSet ||
259 !Expression.UpgradeField(ref Argument1, ref Set1, ref Argument2, ref Set2))
260 {
261 return await this.EvaluateScalarAsync(Argument1, Argument2, Variables);
262 }
263 }
264
265 object x = Argument1.AssociatedObjectValue;
266 object y = Argument2.AssociatedObjectValue;
267
268 if (x is double xd && y is double yd)
269 return await this.EvaluateScalarAsync(xd, yd, Variables);
270
271 if (x is Complex xz && y is Complex yz)
272 return await this.EvaluateScalarAsync(xz, yz, Variables);
273
274 if (x is bool xb && y is bool yb)
275 return await this.EvaluateScalarAsync(xb, yb, Variables);
276
277 if (x is string xs && y is string ys)
278 return await this.EvaluateScalarAsync(xs, ys, Variables);
279
280 double arg1, arg2;
281
282 if (x is double xd2)
283 arg1 = xd2;
284 else
285 {
286 if (x is IPhysicalQuantity Q1)
287 arg1 = Q1.ToPhysicalQuantity().Magnitude;
288 else
289 return await this.EvaluateScalarAsync(Argument1, Argument2, Variables);
290 }
291
292 if (y is double yd2)
293 arg2 = yd2;
294 else
295 {
296 if (y is IPhysicalQuantity Q2)
297 arg2 = Q2.ToPhysicalQuantity().Magnitude;
298 else
299 return await this.EvaluateScalarAsync(Argument1, Argument2, Variables);
300 }
301
302 return await this.EvaluateScalarAsync(arg1, arg2, Variables);
303 }
304 else
305 {
307
308 foreach (IElement E in Argument2.ChildElements)
309 Elements.Add(await this.EvaluateAsync(Argument1, E, Variables));
310
311 return Argument2.Encapsulate(Elements, this);
312 }
313 }
314 else
315 {
316 if (Argument2.IsScalar)
317 {
319
320 foreach (IElement E in Argument1.ChildElements)
321 Elements.Add(await this.EvaluateAsync(E, Argument2, Variables));
322
323 return Argument1.Encapsulate(Elements, this);
324 }
325 else
326 {
327 ICollection<IElement> Argument1Children = Argument1.ChildElements;
328 ICollection<IElement> Argument2Children = Argument2.ChildElements;
329
330 if (Argument1Children.Count == Argument2Children.Count)
331 {
333 IEnumerator<IElement> eArgument1 = Argument1Children.GetEnumerator();
334 IEnumerator<IElement> eArgument2 = Argument2Children.GetEnumerator();
335
336 try
337 {
338 while (eArgument1.MoveNext() && eArgument2.MoveNext())
339 Elements.Add(await this.EvaluateAsync(eArgument1.Current, eArgument2.Current, Variables));
340 }
341 finally
342 {
343 eArgument1.Dispose();
344 eArgument2.Dispose();
345 }
346
347 return Argument1.Encapsulate(Elements, this);
348 }
349 else
350 {
351 ChunkedList<IElement> Argument1Result = new ChunkedList<IElement>();
352
353 foreach (IElement Argument1Child in Argument1Children)
354 {
355 ChunkedList<IElement> Argument2Result = new ChunkedList<IElement>();
356
357 foreach (IElement Argument2Child in Argument2Children)
358 Argument2Result.Add(await this.EvaluateAsync(Argument1Child, Argument2Child, Variables));
359
360 Argument1Result.Add(Argument2.Encapsulate(Argument2Result, this));
361 }
362
363 return Argument1.Encapsulate(Argument1Result, this);
364 }
365 }
366 }
367 }
368
377 {
378 object v1 = Argument1.AssociatedObjectValue;
379 object v2 = Argument2.AssociatedObjectValue;
380
381 if (Expression.TryConvert(v1, out string s1) && Expression.TryConvert(v2, out string s2))
382 return this.EvaluateScalarAsync(s1, s2, Variables);
383 else if (Expression.TryConvert(v1, out double d1) && Expression.TryConvert(v2, out double d2))
384 return this.EvaluateScalarAsync(d1, d2, Variables);
385 else if (Expression.TryConvert(v1, out bool b1) && Expression.TryConvert(v2, out bool b2))
386 return this.EvaluateScalarAsync(b1, b2, Variables);
387 else if (Expression.TryConvert(v1, out Complex z1) && Expression.TryConvert(v2, out Complex z2))
388 return this.EvaluateScalarAsync(z1, z2, Variables);
389 else if (Expression.TryConvert(v1, out Integer i1) && Expression.TryConvert(v2, out Integer i2))
390 return this.EvaluateScalarAsync((double)i1.Value, (double)i2.Value, Variables);
391 else if (Expression.TryConvert(v1, out RationalNumber q1) && Expression.TryConvert(v2, out RationalNumber q2))
392 return this.EvaluateScalarAsync(q1.ToDouble(), q2.ToDouble(), Variables);
393 else
394 throw new ScriptRuntimeException("Type of scalar not supported.", this);
395 }
396
404 public virtual Task<IElement> EvaluateScalarAsync(double Argument1, double Argument2, Variables Variables)
405 {
406 return Task.FromResult(this.EvaluateScalar(Argument1, Argument2, Variables));
407 }
408
416 public virtual Task<IElement> EvaluateScalarAsync(Complex Argument1, Complex Argument2, Variables Variables)
417 {
418 return Task.FromResult(this.EvaluateScalar(Argument1, Argument2, Variables));
419 }
420
428 public virtual Task<IElement> EvaluateScalarAsync(bool Argument1, bool Argument2, Variables Variables)
429 {
430 return Task.FromResult(this.EvaluateScalar(Argument1, Argument2, Variables));
431 }
432
440 public virtual Task<IElement> EvaluateScalarAsync(string Argument1, string Argument2, Variables Variables)
441 {
442 return Task.FromResult(this.EvaluateScalar(Argument1, Argument2, Variables));
443 }
444
445 }
446}
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
void Add(T Item)
Adds an item to the collection.
Definition: ChunkedList.cs:272
Class managing a script expression.
Definition: Expression.cs:41
static bool TryConvert(object Value, Type DesiredType, bool AcceptInformationLoss, out object Result)
Tries to convert an object Value to an object of type DesiredType .
Definition: Expression.cs:5530
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:5327
Base class for funcions of two scalar variables.
virtual Task< IElement > EvaluateScalarAsync(double Argument1, double Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual IElement EvaluateScalar(double Argument1, double Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual IElement EvaluateScalar(Complex Argument1, Complex Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual IElement EvaluateScalar(IElement Argument1, IElement Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual Task< IElement > EvaluateScalarAsync(string Argument1, string Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual Task< IElement > EvaluateScalarAsync(bool Argument1, bool Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual Task< IElement > EvaluateScalarAsync(IElement Argument1, IElement Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
override async Task< IElement > EvaluateAsync(IElement Argument1, IElement Argument2, Variables Variables)
Evaluates the function.
override IElement Evaluate(IElement Argument1, IElement Argument2, Variables Variables)
Evaluates the function.
virtual IElement EvaluateScalar(bool Argument1, bool Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual IElement EvaluateScalar(string Argument1, string Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
abstract bool UpgradeScalarsToSameSet
If scalars should be upgraded to the same set before evaluation.
FunctionTwoScalarVariables(ScriptNode Argument1, ScriptNode Argument2, int Start, int Length, Expression Expression)
Base class for funcions of one scalar variable.
virtual Task< IElement > EvaluateScalarAsync(Complex Argument1, Complex Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
Base class for funcions of one variable.
ScriptNode Argument2
Function argument 2.
ScriptNode Argument1
Function argument 1.
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
Integer-valued number.
Definition: Integer.cs:13
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:21
Basic interface for all types of sets.
Definition: ISet.cs:10
Interface for objects that can be represented as a physical quantity.