2using System.Threading.Tasks;
45 public IEnumerable<KeyValuePair<ScriptNode, ScriptNode>>
BoundVariables => this.boundVariables;
50 public IEnumerable<IFilterNode>
Filter => this.filter;
73 if (this.triples is
null)
76 this.triples.
Add(Triple);
86 if (this.boundVariables is
null)
89 this.boundVariables.
Add(
new KeyValuePair<ScriptNode, ScriptNode>(Value,
Variable));
98 if (this.filter is
null)
102 this.filter.
Add(FilterNode);
144 ExistingMatches = await this.CrossPossibilitiesOneVariable(ExistingMatches, T, 0, 1, 2, Cube);
148 ExistingMatches = await this.CrossPossibilitiesOneVariable(ExistingMatches, T, 1, 0, 2, Cube);
152 ExistingMatches = await this.CrossPossibilitiesOneVariable(ExistingMatches, T, 2, 0, 1, Cube);
156 ExistingMatches = await this.CrossPossibilitiesTwoVariables(ExistingMatches, T, 0, 1, 2, Cube);
160 ExistingMatches = await this.CrossPossibilitiesTwoVariables(ExistingMatches, T, 0, 2, 1, Cube);
164 ExistingMatches = await this.CrossPossibilitiesTwoVariables(ExistingMatches, T, 1, 2, 0, Cube);
168 ExistingMatches = await this.CrossPossibilitiesThreeVariables(ExistingMatches, T, Cube);
172 if (ExistingMatches is
null)
175 using (IEnumerator<Possibility> e = ExistingMatches.GetEnumerator())
183 if (this.HasBoundVariables && !(ExistingMatches is
null))
194 foreach (KeyValuePair<ScriptNode, ScriptNode> P2
in this.boundVariables)
196 if (RecordVariables is
null)
199 RecordVariables.Object = P;
202 Name = Ref.VariableName;
205 object Obj = await
SparqlQuery.EvaluateValue(RecordVariables, P2.Value);
209 Name = Obj.ToString();
210 if (
string.IsNullOrEmpty(Name))
214 ISemanticElement Literal = await Query.EvaluateSemanticElement(RecordVariables, P2.Key);
215 if (!(Literal is
null))
222 ExistingMatches = NewMatches;
225 if (this.HasFilter && !(ExistingMatches is
null))
233 if (RecordVariables is
null)
236 RecordVariables.Object = P;
242 object Value = await
SparqlQuery.EvaluateValue(RecordVariables,
Filter, Cube, Query, P);
243 if (!(Value is
bool b) || !b)
252 if (Filtered is
null)
259 ExistingMatches = Filtered;
262 return ExistingMatches;
265 private async Task<IEnumerable<Possibility>> CrossPossibilitiesOneVariable(
273 if (Possibilities is
null)
275 IEnumerable<ISemanticTriple> NewTriples = await Cube.
GetTriples(
276 T[ValueIndex1], ValueIndex1, T[ValueIndex2], ValueIndex2);
278 if (NewTriples is
null)
293 IEnumerable<ISemanticTriple> NewTriples = await Cube.
GetTriples(
294 T[ValueIndex1], ValueIndex1, T[ValueIndex2], ValueIndex2);
296 if (NewTriples is
null)
299 if (NewPossibilities is
null)
303 NewPossibilities.
Add(
new Possibility(Name, T2[VariableIndex], P));
310 if (NewPossibilities is
null)
313 NewPossibilities.
Add(P);
318 return NewPossibilities;
321 private async Task<IEnumerable<Possibility>> CrossPossibilitiesTwoVariables(
330 bool SameName = Name == Name2;
332 if (Possibilities is
null)
334 IEnumerable<ISemanticTriple>
Triples = await Cube.
GetTriples(T[ValueIndex], ValueIndex);
344 if (!E.Equals(T2[VariableIndex2]))
347 if (NewPossibilities is
null)
354 if (NewPossibilities is
null)
357 NewPossibilities.
Add(
374 bool IsProcessed = !(Value is
null);
375 bool IsProcessed2 = !(Value2 is
null);
377 if (IsProcessed && IsProcessed2)
382 if (NewPossibilities is
null)
385 NewPossibilities.
Add(P);
387 else if (IsProcessed)
389 this.CrossPossibilities(
390 await Cube.
GetTriples(Value, VariableIndex1, T[ValueIndex], ValueIndex),
391 P, Name2, VariableIndex2, ref NewPossibilities);
393 else if (IsProcessed2)
395 this.CrossPossibilities(
396 await Cube.
GetTriples(Value2, VariableIndex2, T[ValueIndex], ValueIndex),
397 P, Name, VariableIndex1, ref NewPossibilities);
401 IEnumerable<ISemanticTriple>
Triples = await Cube.
GetTriples(T[ValueIndex], ValueIndex);
411 if (!E.Equals(T2[VariableIndex2]))
414 if (NewPossibilities is
null)
421 if (NewPossibilities is
null)
424 NewPossibilities.
Add(
434 return NewPossibilities;
437 private async Task<IEnumerable<Possibility>> CrossPossibilitiesThreeVariables(
444 bool SameName = Name == Name2;
445 bool SameName2 = Name == Name3;
446 bool SameName3 = Name2 == Name3;
448 if (Possibilities is
null)
466 if (!SameName2 && !SameName3)
469 if (NewPossibilities is
null)
472 NewPossibilities.
Add(NewPossibility);
482 bool IsProcessed = !(Value is
null);
483 bool IsProcessed2 = !(Value2 is
null);
484 bool IsProcessed3 = !(Value3 is
null);
486 if (IsProcessed && IsProcessed2 && IsProcessed3)
488 if (await Cube.GetTriplesBySubjectAndPredicateAndObject(Value, Value2, Value3) is
null)
491 if (NewPossibilities is
null)
494 NewPossibilities.
Add(P);
496 else if (IsProcessed && IsProcessed2)
498 this.CrossPossibilities(
499 await Cube.GetTriplesBySubjectAndPredicate(Value, Value2),
500 P, Name3, 2, ref NewPossibilities);
502 else if (IsProcessed && IsProcessed3)
504 this.CrossPossibilities(
505 await Cube.GetTriplesBySubjectAndObject(Value, Value3),
506 P, Name2, 1, ref NewPossibilities);
508 else if (IsProcessed2 && IsProcessed3)
510 this.CrossPossibilities(
511 await Cube.GetTriplesByPredicateAndObject(Value2, Value3),
512 P, Name, 0, ref NewPossibilities);
514 else if (IsProcessed)
527 if (NewPossibilities is
null)
534 if (NewPossibilities is
null)
537 NewPossibilities.
Add(
543 else if (IsProcessed2)
556 if (NewPossibilities is
null)
563 if (NewPossibilities is
null)
566 NewPossibilities.
Add(
572 else if (IsProcessed3)
585 if (NewPossibilities is
null)
592 if (NewPossibilities is
null)
595 NewPossibilities.
Add(
619 if (!SameName2 && !SameName3)
622 if (NewPossibilities is
null)
625 NewPossibilities.
Add(NewPossibility);
631 return NewPossibilities;
634 private void CrossPossibilities(IEnumerable<ISemanticTriple> NewTriples,
637 if (NewTriples is
null)
640 if (NewPossibilities is
null)
658 if (!(this.triples is
null))
664 if (!S.Node.ForAllChildNodes(Callback, State, Order))
670 if (!P.Node.ForAllChildNodes(Callback, State, Order))
676 if (!O.Node.ForAllChildNodes(Callback, State, Order))
682 if (!(this.boundVariables is
null))
684 foreach (KeyValuePair<ScriptNode, ScriptNode> P
in this.boundVariables)
686 if (!P.Key.ForAllChildNodes(Callback, State, Order))
689 if (!P.Value.ForAllChildNodes(Callback, State, Order))
694 if (!(this.filter is
null))
698 if (!P.ScriptNode.ForAllChildNodes(Callback, State, Order))
704 this.
ForAll(Callback, State, Order);
708 if (!(this.triples is
null))
714 if (!S.Node.ForAllChildNodes(Callback, State, Order))
720 if (!P.Node.ForAllChildNodes(Callback, State, Order))
726 if (!O.Node.ForAllChildNodes(Callback, State, Order))
732 if (!(this.boundVariables is
null))
734 foreach (KeyValuePair<ScriptNode, ScriptNode> P
in this.boundVariables)
736 if (!P.Key.ForAllChildNodes(Callback, State, Order))
739 if (!P.Value.ForAllChildNodes(Callback, State, Order))
744 if (!(this.filter is
null))
748 if (!P.ScriptNode.ForAllChildNodes(Callback, State, Order))
768 if (!(this.triples is
null))
773 while (!(Loop is
null))
775 for (i = Loop.
Start, c = Loop.
Pos; i < c; i++)
781 if (!S.ForAll(Callback, State, Order))
787 if (!P.ForAll(Callback, State, Order))
793 if (!O.ForAll(Callback, State, Order))
802 if (!(this.boundVariables is
null))
805 KeyValuePair<ScriptNode, ScriptNode> P;
807 while (!(Loop is
null))
809 for (i = Loop.
Start, c = Loop.
Pos; i < c; i++)
813 if (!Callback(P.Key, out
ScriptNode NewKey, State))
816 if (!Callback(P.Value, out
ScriptNode NewValue, State))
819 if (!(NewKey is
null) || !(NewValue is
null))
821 Loop[i] =
new KeyValuePair<ScriptNode, ScriptNode>(
822 NewKey ?? P.Key, NewValue ?? P.Value);
830 if (!(this.filter is
null))
834 while (!(Loop is
null))
836 for (i = Loop.
Start, c = Loop.
Pos; i < c; i++)
841 if (!(NewValue is
null))
844 Loop[i] = NewFilterNode;
861 this.triples is
null ^ Typed.triples is
null ||
862 this.boundVariables is
null ^ Typed.boundVariables is
null ||
863 this.filter is
null ^ Typed.filter is
null)
868 if (!(this.boundVariables is
null))
870 IEnumerator<KeyValuePair<ScriptNode, ScriptNode>> e1 = this.boundVariables.
GetEnumerator();
871 IEnumerator<KeyValuePair<ScriptNode, ScriptNode>> e2 = Typed.boundVariables.GetEnumerator();
875 bool b1 = e1.MoveNext();
876 bool b2 = e2.MoveNext();
880 if (!e1.Current.Equals(e2.Current))
897 if (!(this.filter is
null))
900 IEnumerator<IFilterNode> e2 = Typed.filter.GetEnumerator();
904 bool b1 = e1.MoveNext();
905 bool b2 = e2.MoveNext();
909 if (!e1.Current.Equals(e2.Current))
932 int Result = base.GetHashCode();
934 if (!(this.triples is
null))
937 Result ^= Result << 5 ^ T.GetHashCode();
940 if (!(this.boundVariables is
null))
942 foreach (KeyValuePair<ScriptNode, ScriptNode> P
in this.boundVariables)
944 Result ^= Result << 5 ^ P.Key.GetHashCode();
945 Result ^= Result << 5 ^ P.Value.GetHashCode();
949 if (!(this.filter is
null))
952 Result ^= Result << 5 ^ N.GetHashCode();
964 if (!(this.triples is
null))
969 S.Node.SetParent(Parent);
972 P.Node.SetParent(Parent);
975 O.Node.SetParent(Parent);
979 if (!(this.boundVariables is
null))
981 foreach (KeyValuePair<ScriptNode, ScriptNode> P
in this.boundVariables)
983 P.Key.SetParent(Parent);
984 P.Value.SetParent(Parent);
988 if (!(this.filter is
null))
991 P.ScriptNode.SetParent(Parent);
Node referencing a chunk in a ChunkedList<T>
ChunkNode< T > Next
Next chunk
int Pos
Index after the last element in chunk.
int Start
Index of first element in chunk.
A chunked list is a linked list of chunks of objects of type T .
IEnumerator< T > GetEnumerator()
Returns an enumerator for the collection.
ChunkNode< T > FirstChunk
First chunk
int Count
Number of elements in collection.
void Add(T Item)
Adds an item to the collection.
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 or created.
override int GetHashCode()
void AddTriple(SemanticQueryTriple Triple)
Adds a triple to the pattern
ChunkedList< SemanticQueryTriple > Triples
Triples, null if none.
bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
Calls the callback method for all child nodes.
int TripleCount
Number of triples registered.
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.
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