1using System.Collections.Generic;
2using System.Threading.Tasks;
15 private LinkedList<SemanticQueryTriple> triples =
null;
16 private LinkedList<KeyValuePair<ScriptNode, ScriptNode>> boundVariables =
null;
17 private LinkedList<IFilterNode> filter =
null;
34 public IEnumerable<SemanticQueryTriple>
Triples => this.triples;
39 public IEnumerable<KeyValuePair<ScriptNode, ScriptNode>>
BoundVariables => this.boundVariables;
44 public IEnumerable<IFilterNode>
Filter => this.filter;
67 if (this.triples is
null)
68 this.triples =
new LinkedList<SemanticQueryTriple>();
70 this.triples.AddLast(Triple);
80 if (this.boundVariables is
null)
81 this.boundVariables =
new LinkedList<KeyValuePair<ScriptNode, ScriptNode>>();
83 this.boundVariables.AddLast(
new KeyValuePair<ScriptNode, ScriptNode>(Value,
Variable));
92 if (this.filter is
null)
93 this.filter =
new LinkedList<IFilterNode>();
96 this.filter.AddLast(FilterNode);
138 ExistingMatches = await this.CrossPossibilitiesOneVariable(ExistingMatches, T, 0, 1, 2, Cube);
142 ExistingMatches = await this.CrossPossibilitiesOneVariable(ExistingMatches, T, 1, 0, 2, Cube);
146 ExistingMatches = await this.CrossPossibilitiesOneVariable(ExistingMatches, T, 2, 0, 1, Cube);
150 ExistingMatches = await this.CrossPossibilitiesTwoVariables(ExistingMatches, T, 0, 1, 2, Cube);
154 ExistingMatches = await this.CrossPossibilitiesTwoVariables(ExistingMatches, T, 0, 2, 1, Cube);
158 ExistingMatches = await this.CrossPossibilitiesTwoVariables(ExistingMatches, T, 1, 2, 0, Cube);
162 ExistingMatches = await this.CrossPossibilitiesThreeVariables(ExistingMatches, T, Cube);
166 if (ExistingMatches is
null || !ExistingMatches.GetEnumerator().MoveNext())
171 if (this.HasBoundVariables && !(ExistingMatches is
null))
173 LinkedList<Possibility> NewMatches =
new LinkedList<Possibility>();
182 foreach (KeyValuePair<ScriptNode, ScriptNode> P2
in this.boundVariables)
184 if (RecordVariables is
null)
187 RecordVariables.Object = P;
190 Name = Ref.VariableName;
193 object Obj = await
SparqlQuery.EvaluateValue(RecordVariables, P2.Value);
197 Name = Obj.ToString();
198 if (
string.IsNullOrEmpty(Name))
202 ISemanticElement Literal = await Query.EvaluateSemanticElement(RecordVariables, P2.Key);
203 if (!(Literal is
null))
207 NewMatches.AddLast(P);
210 ExistingMatches = NewMatches;
213 if (this.HasFilter && !(ExistingMatches is
null))
215 LinkedList<Possibility> Filtered =
null;
221 if (RecordVariables is
null)
224 RecordVariables.Object = P;
230 object Value = await
SparqlQuery.EvaluateValue(RecordVariables,
Filter, Cube, Query, P);
231 if (!(Value is
bool b) || !b)
240 if (Filtered is
null)
241 Filtered =
new LinkedList<Possibility>();
247 ExistingMatches = Filtered;
250 return ExistingMatches;
253 private async Task<IEnumerable<Possibility>> CrossPossibilitiesOneVariable(
257 LinkedList<Possibility> NewPossibilities =
null;
261 if (Possibilities is
null)
263 IEnumerable<ISemanticTriple> NewTriples = await Cube.
GetTriples(
264 T[ValueIndex1], ValueIndex1, T[ValueIndex2], ValueIndex2);
266 if (NewTriples is
null)
269 NewPossibilities =
new LinkedList<Possibility>();
272 NewPossibilities.AddLast(
new Possibility(Name, T2[VariableIndex]));
281 IEnumerable<ISemanticTriple> NewTriples = await Cube.
GetTriples(
282 T[ValueIndex1], ValueIndex1, T[ValueIndex2], ValueIndex2);
284 if (NewTriples is
null)
287 if (NewPossibilities is
null)
288 NewPossibilities =
new LinkedList<Possibility>();
291 NewPossibilities.AddLast(
new Possibility(Name, T2[VariableIndex], P));
298 if (NewPossibilities is
null)
299 NewPossibilities =
new LinkedList<Possibility>();
301 NewPossibilities.AddLast(P);
306 return NewPossibilities;
309 private async Task<IEnumerable<Possibility>> CrossPossibilitiesTwoVariables(
313 LinkedList<Possibility> NewPossibilities =
null;
318 bool SameName = Name == Name2;
320 if (Possibilities is
null)
322 IEnumerable<ISemanticTriple>
Triples = await Cube.
GetTriples(T[ValueIndex], ValueIndex);
332 if (!E.Equals(T2[VariableIndex2]))
335 if (NewPossibilities is
null)
336 NewPossibilities =
new LinkedList<Possibility>();
338 NewPossibilities.AddLast(
new Possibility(Name, E));
342 if (NewPossibilities is
null)
343 NewPossibilities =
new LinkedList<Possibility>();
345 NewPossibilities.AddLast(
362 bool IsProcessed = !(Value is
null);
363 bool IsProcessed2 = !(Value2 is
null);
365 if (IsProcessed && IsProcessed2)
370 if (NewPossibilities is
null)
371 NewPossibilities =
new LinkedList<Possibility>();
373 NewPossibilities.AddLast(P);
375 else if (IsProcessed)
377 this.CrossPossibilities(
378 await Cube.
GetTriples(Value, VariableIndex1, T[ValueIndex], ValueIndex),
379 P, Name2, VariableIndex2, ref NewPossibilities);
381 else if (IsProcessed2)
383 this.CrossPossibilities(
384 await Cube.
GetTriples(Value2, VariableIndex2, T[ValueIndex], ValueIndex),
385 P, Name, VariableIndex1, ref NewPossibilities);
389 IEnumerable<ISemanticTriple>
Triples = await Cube.
GetTriples(T[ValueIndex], ValueIndex);
399 if (!E.Equals(T2[VariableIndex2]))
402 if (NewPossibilities is
null)
403 NewPossibilities =
new LinkedList<Possibility>();
405 NewPossibilities.AddLast(
410 if (NewPossibilities is
null)
411 NewPossibilities =
new LinkedList<Possibility>();
413 NewPossibilities.AddLast(
423 return NewPossibilities;
426 private async Task<IEnumerable<Possibility>> CrossPossibilitiesThreeVariables(
429 LinkedList<Possibility> NewPossibilities =
null;
433 bool SameName = Name == Name2;
434 bool SameName2 = Name == Name3;
435 bool SameName3 = Name2 == Name3;
437 if (Possibilities is
null)
455 if (!SameName2 && !SameName3)
458 if (NewPossibilities is
null)
459 NewPossibilities =
new LinkedList<Possibility>();
461 NewPossibilities.AddLast(NewPossibility);
471 bool IsProcessed = !(Value is
null);
472 bool IsProcessed2 = !(Value2 is
null);
473 bool IsProcessed3 = !(Value3 is
null);
475 if (IsProcessed && IsProcessed2 && IsProcessed3)
477 if (await Cube.GetTriplesBySubjectAndPredicateAndObject(Value, Value2, Value3) is
null)
480 if (NewPossibilities is
null)
481 NewPossibilities =
new LinkedList<Possibility>();
483 NewPossibilities.AddLast(P);
485 else if (IsProcessed && IsProcessed2)
487 this.CrossPossibilities(
488 await Cube.GetTriplesBySubjectAndPredicate(Value, Value2),
489 P, Name3, 2, ref NewPossibilities);
491 else if (IsProcessed && IsProcessed3)
493 this.CrossPossibilities(
494 await Cube.GetTriplesBySubjectAndObject(Value, Value3),
495 P, Name2, 1, ref NewPossibilities);
497 else if (IsProcessed2 && IsProcessed3)
499 this.CrossPossibilities(
500 await Cube.GetTriplesByPredicateAndObject(Value2, Value3),
501 P, Name, 0, ref NewPossibilities);
503 else if (IsProcessed)
516 if (NewPossibilities is
null)
517 NewPossibilities =
new LinkedList<Possibility>();
519 NewPossibilities.AddLast(
524 if (NewPossibilities is
null)
525 NewPossibilities =
new LinkedList<Possibility>();
527 NewPossibilities.AddLast(
533 else if (IsProcessed2)
546 if (NewPossibilities is
null)
547 NewPossibilities =
new LinkedList<Possibility>();
549 NewPossibilities.AddLast(
554 if (NewPossibilities is
null)
555 NewPossibilities =
new LinkedList<Possibility>();
557 NewPossibilities.AddLast(
563 else if (IsProcessed3)
576 if (NewPossibilities is
null)
577 NewPossibilities =
new LinkedList<Possibility>();
579 NewPossibilities.AddLast(
584 if (NewPossibilities is
null)
585 NewPossibilities =
new LinkedList<Possibility>();
587 NewPossibilities.AddLast(
611 if (!SameName2 && !SameName3)
614 if (NewPossibilities is
null)
615 NewPossibilities =
new LinkedList<Possibility>();
617 NewPossibilities.AddLast(NewPossibility);
623 return NewPossibilities;
626 private void CrossPossibilities(IEnumerable<ISemanticTriple> NewTriples,
629 if (NewTriples is
null)
632 if (NewPossibilities is
null)
633 NewPossibilities =
new LinkedList<Possibility>();
650 if (!(this.triples is
null))
656 if (!S.Node.ForAllChildNodes(Callback, State, Order))
662 if (!P.Node.ForAllChildNodes(Callback, State, Order))
668 if (!O.Node.ForAllChildNodes(Callback, State, Order))
674 if (!(this.boundVariables is
null))
676 foreach (KeyValuePair<ScriptNode, ScriptNode> P
in this.boundVariables)
678 if (!P.Key.ForAllChildNodes(Callback, State, Order))
681 if (!P.Value.ForAllChildNodes(Callback, State, Order))
686 if (!(this.filter is
null))
690 if (!P.ScriptNode.ForAllChildNodes(Callback, State, Order))
696 this.
ForAll(Callback, State, Order);
700 if (!(this.triples is
null))
706 if (!S.Node.ForAllChildNodes(Callback, State, Order))
712 if (!P.Node.ForAllChildNodes(Callback, State, Order))
718 if (!O.Node.ForAllChildNodes(Callback, State, Order))
724 if (!(this.boundVariables is
null))
726 foreach (KeyValuePair<ScriptNode, ScriptNode> P
in this.boundVariables)
728 if (!P.Key.ForAllChildNodes(Callback, State, Order))
731 if (!P.Value.ForAllChildNodes(Callback, State, Order))
736 if (!(this.filter is
null))
740 if (!P.ScriptNode.ForAllChildNodes(Callback, State, Order))
758 if (!(this.triples is
null))
764 if (!S.ForAll(Callback, State, Order))
770 if (!P.ForAll(Callback, State, Order))
776 if (!O.ForAll(Callback, State, Order))
782 if (!(this.boundVariables is
null))
784 LinkedListNode<KeyValuePair<ScriptNode, ScriptNode>> Loop = this.boundVariables.First;
786 while (!(Loop is
null))
788 if (!Callback(Loop.Value.Key, out
ScriptNode NewKey, State))
791 if (!Callback(Loop.Value.Value, out
ScriptNode NewValue, State))
794 if (!(NewKey is
null) || !(NewValue is
null))
796 Loop.Value =
new KeyValuePair<ScriptNode, ScriptNode>(
797 NewKey ?? Loop.Value.Key, NewValue ?? Loop.Value.Value);
804 if (!(this.filter is
null))
806 LinkedListNode<IFilterNode> Loop = this.filter.First;
808 while (!(Loop is
null))
810 if (!Callback(Loop.Value.ScriptNode, out
ScriptNode NewValue, State))
813 if (!(NewValue is
null))
816 Loop.Value = NewFilterNode;
832 this.triples is
null ^ Typed.triples is
null ||
833 this.boundVariables is
null ^ Typed.boundVariables is
null ||
834 this.filter is
null ^ Typed.filter is
null)
839 if (!(this.boundVariables is
null))
841 IEnumerator<KeyValuePair<ScriptNode, ScriptNode>> e1 = this.boundVariables.GetEnumerator();
842 IEnumerator<KeyValuePair<ScriptNode, ScriptNode>> e2 = Typed.boundVariables.GetEnumerator();
843 bool b1 = e1.MoveNext();
844 bool b2 = e2.MoveNext();
848 if (!e1.Current.Equals(e2.Current))
859 if (!(this.filter is
null))
861 IEnumerator<IFilterNode> e1 = this.filter.GetEnumerator();
862 IEnumerator<IFilterNode> e2 = Typed.filter.GetEnumerator();
863 bool b1 = e1.MoveNext();
864 bool b2 = e2.MoveNext();
868 if (!e1.Current.Equals(e2.Current))
885 int Result = base.GetHashCode();
887 if (!(this.triples is
null))
890 Result ^= Result << 5 ^ T.GetHashCode();
893 if (!(this.boundVariables is
null))
895 foreach (KeyValuePair<ScriptNode, ScriptNode> P
in this.boundVariables)
897 Result ^= Result << 5 ^ P.Key.GetHashCode();
898 Result ^= Result << 5 ^ P.Value.GetHashCode();
902 if (!(this.filter is
null))
905 Result ^= Result << 5 ^ N.GetHashCode();
917 if (!(this.triples is
null))
922 S.Node.SetParent(Parent);
925 P.Node.SetParent(Parent);
928 O.Node.SetParent(Parent);
932 if (!(this.boundVariables is
null))
934 foreach (KeyValuePair<ScriptNode, ScriptNode> P
in this.boundVariables)
936 P.Key.SetParent(Parent);
937 P.Value.SetParent(Parent);
941 if (!(this.filter is
null))
944 P.ScriptNode.SetParent(Parent);
Base class for all nodes in a parsed script tree.
Represents a variable reference.
Makes a script node, a filter node.
Represents a pattern in a SPARQL query.
void AddFilter(ScriptNode Filter)
Adds a filter to the pattern.
void SetParent(ScriptNode Parent)
Sets the parent node. Can only be used when expression is being parsed.
override int GetHashCode()
void AddTriple(SemanticQueryTriple Triple)
Adds a triple to the pattern
bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
Calls the callback method for all child nodes.
SparqlRegularPattern()
Represents a pattern in a SPARQL query.
bool HasBoundVariables
If pattern has bound variables
bool HasTriples
If pattern has triples
Task< IEnumerable< Possibility > > Search(ISemanticCube Cube, Variables Variables, SparqlQuery Query)
Searches for the pattern on information in a semantic cube.
async Task< IEnumerable< Possibility > > Search(ISemanticCube Cube, Variables Variables, IEnumerable< Possibility > ExistingMatches, SparqlQuery Query)
Searches for the pattern on information in a semantic cube.
bool IsEmpty
If pattern is empty.
IEnumerable< SemanticQueryTriple > Triples
Triples, null if none.
bool HasFilter
If pattern has filter
bool ForAll(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
Calls the callback method for all child nodes.
override bool Equals(object obj)
void AddVariableBinding(ScriptNode Value, ScriptNode Variable)
Adds a variable binding to the pattern.
IEnumerable< IFilterNode > Filter
Filter, null if none.
IEnumerable< KeyValuePair< ScriptNode, ScriptNode > > BoundVariables
Bound variables, null if none.
Represents a possible solution during SPARQL evaluation.
ISemanticElement GetValue(string VariableName)
Access to possible variable values, given a variable name.
string VariableName(int Index)
Gets a variable name, given the axis index: 0=Subject, 1=Predicate, 2=Object.
string PredicateVariable
Predicate element variable name, if any
string ObjectVariable
Object element variable name, if any
ISemanticElement Object
Object element
ISemanticElement Predicate
Predicate element
ISemanticElement Subject
Subject element
QueryTripleType Type
Type of triple
string SubjectVariable
Subject element variable name, if any
Semantic element based on script.
Contains information about a variable.
Interface for semantic cubes.
Task< IEnumerable< ISemanticTriple > > GetTriples(ISemanticElement Value, int AxisIndex)
Gets available triples in the cube, having a given value, along a given axis.
Task< IEnumerable< ISemanticTriple > > GetTriplesBySubjectAndPredicateAndObject(ISemanticElement Subject, ISemanticElement Predicate, ISemanticElement Object)
Gets available triples in the cube, having a given subject, predicate and object.
Interface for semantic nodes.
Interface for semantic planes.
Interface for semantic triples.
ISemanticElement Object
Object element
ISemanticElement Predicate
Predicate element
ISemanticElement Subject
Subject element
Interface for filter nodes.
Interface for SPARQL patterns.
delegate bool ScriptNodeEventHandler(ScriptNode Node, out ScriptNode NewNode, object State)
Delegate for ScriptNode callback methods.
SearchMethod
Method to traverse the expression structure
QueryTripleType
Type of query triple