/// <summary> /// Adds a new path to the list of current incomplete paths. /// </summary> /// <param name="p">Path.</param> public void AddPath(PotentialPath p) { if (!_incompletePaths.Contains(p)) { _incompletePaths.Add(p); } }
/// <summary> /// Creates a new Potential Path which is a copy of an existing Path /// </summary> /// <param name="p">Potentuak Path</param> public PotentialPath(PotentialPath p) { this._start = p.Start; this._current = p.Current; this._complete = p.IsComplete; this._deadend = p.IsDeadEnd; this._partial = p.IsPartial; this._length = p.Length; }
/// <summary> /// Adds a new path to the list of complete paths. /// </summary> /// <param name="p">Path.</param> public void AddCompletePath(PotentialPath p) { if (p.IsComplete && !p.IsPartial) { if (!_completePaths.Contains(p)) { _completePaths.Add(p); } } }
/// <summary> /// Checks whether the other object is an equivalent potential path /// </summary> /// <param name="obj">Object to test</param> /// <returns></returns> public override bool Equals(object obj) { if (obj is PotentialPath) { PotentialPath other = (PotentialPath)obj; return(this._start.Equals(other.Start) && this._current.Equals(other.Current)); } else { return(false); } }
/// <summary> /// Evaluates the Path using the given Path Evaluation Context. /// </summary> /// <param name="context">Path Evaluation Context.</param> public void Evaluate(PathEvaluationContext context) { IEnumerable <Triple> ts; if (context.IsFirst) { // First thing firsts we'll set that the path is no longer at the first thing since we're the first thing! context.IsFirst = false; // We're the start of a Path if (context.PathStart.VariableName != null) { // Path starts from a Variable String var = context.PathStart.VariableName; if (context.SparqlContext.InputMultiset.ContainsVariable(var)) { // Path starts from a Variable for which we have existing values IEnumerable <INode> values = (from s in context.SparqlContext.InputMultiset.Sets where s.ContainsVariable(var) select s[var]).Distinct(); foreach (INode n in values) { if (context.IsReversed) { // If the Path is currently reversed then we'll look at triples with the given Predicate-Object pair ts = context.SparqlContext.Data.GetTriplesWithPredicateObject(_predicate, n); } else { // For normal forward paths we'll look at triples with the given Subject-Predicate pair ts = context.SparqlContext.Data.GetTriplesWithSubjectPredicate(n, _predicate); } // Bind path as appropriate foreach (Triple t in ts) { PotentialPath p; if (context.IsReversed) { p = new PotentialPath(n, t.Subject); } else { p = new PotentialPath(n, t.Object); } context.AddPath(p); } } } else { // Path starts from an as yet unbound Variable ts = context.SparqlContext.Data.GetTriplesWithPredicate(_predicate); // Bind paths as appropriate foreach (Triple t in ts) { PotentialPath p; if (context.IsReversed) { p = new PotentialPath(t.Object, t.Subject); } else { p = new PotentialPath(t.Subject, t.Object); } context.AddPath(p); } } } else { // Path starts from a fixed value INode fixedSubj = ((NodeMatchPattern)context.PathStart).Node; if (context.IsReversed) { // If the Path is currently reversed then we'll look at triples with the given Predicate-Object pair ts = context.SparqlContext.Data.GetTriplesWithPredicateObject(_predicate, fixedSubj); } else { // For normal forward paths we'll look at triples with the given Subject-Predicate pair ts = context.SparqlContext.Data.GetTriplesWithSubjectPredicate(fixedSubj, _predicate); } // Map each Triple as a Path foreach (Triple t in ts) { PotentialPath p; if (context.IsReversed) { p = new PotentialPath(t.Object, fixedSubj); } else { p = new PotentialPath(fixedSubj, t.Object); } context.AddPath(p); } } } else { // We're not the start of a Path so we're continuing from a previous path // This means all paths must continue from the Current position of an incomplete path // If we are permitted to introduce new paths we can go ahead and do that here if (context.PermitsNewPaths) { // Introduce new paths based on the predicate at this stage ts = context.SparqlContext.Data.GetTriplesWithPredicate(_predicate); foreach (Triple t in ts) { PotentialPath p; if (context.IsReversed) { p = new PotentialPath(t.Object, t.Object); p.Length = 0; } else { p = new PotentialPath(t.Subject, t.Subject); p.Length = 0; } context.AddPath(p); } context.PermitsNewPaths = false; } // If there are no incomplete paths we abort if (context.Paths.Count == 0) { return; } // For each incomplete path we attempt to extend the Path HashSet <PotentialPath> incomplete = new HashSet <PotentialPath>(); foreach (PotentialPath p in context.Paths) { // Ignore dead-end paths if (p.IsDeadEnd) { continue; } if (context.IsReversed) { ts = context.SparqlContext.Data.GetTriplesWithPredicateObject(_predicate, p.Current); } else { ts = context.SparqlContext.Data.GetTriplesWithSubjectPredicate(p.Current, _predicate); } // int c = 0; foreach (Triple t in ts) { PotentialPath p2;; if (context.IsReversed) { p2 = new PotentialPath(p.Start, t.Subject); p2.Length = p.Length + 1; } else { p2 = new PotentialPath(p.Start, t.Object); p2.Length = p.Length + 1; } incomplete.Add(p2); } } // Add the newly found paths to the set of incomplete paths foreach (PotentialPath p in incomplete) { context.AddPath(p); } } // If we're the Last thing in the Path we can now mark any completed paths if (context.IsLast) { bool objVar = (context.PathEnd.VariableName != null); bool objVarBound = (objVar && context.SparqlContext.InputMultiset.ContainsVariable(context.PathEnd.VariableName)); foreach (PotentialPath p in context.Paths) { if (!p.IsDeadEnd && !p.IsComplete && !p.IsPartial) { if (objVar) { if (objVarBound) { // If the end of the Path is a previously bound variable then we do an accepts check if (context.PathEnd.Accepts(context.SparqlContext, p.Current)) { p.IsComplete = true; context.AddCompletePath(p); } else { // We can mark this path as partial (I think) since it itself can't be completed // but there's a possibility that it might lead to a completable path at a later point p.IsPartial = true; } } else { // If the end of the Path is an as yet unbound variable then any value is acceptable p.IsComplete = true; context.AddCompletePath(p); } } else { if (context.PathEnd.Accepts(context.SparqlContext, p.Current)) { // If the Path End accepts the current path end we can complete it p.IsComplete = true; context.AddCompletePath(p); } else { // We can mark this path as partial (I think) since it itself can't be completed // but there's a possibility that it might lead to a completable path at a later point p.IsPartial = true; } } } } if (context.CanAbortEarly) { if (context.CompletePaths.Any(p => context.PathStart.Accepts(context.SparqlContext, p.Start) && context.PathEnd.Accepts(context.SparqlContext, p.Current))) { throw new RdfQueryPathFoundException(); } } } }
/// <summary> /// Adds a new path to the list of complete paths /// </summary> /// <param name="p">Path</param> public void AddCompletePath(PotentialPath p) { if (p.IsComplete && !p.IsPartial) { if (!this._completePaths.Contains(p)) { this._completePaths.Add(p); } } }
/// <summary> /// Adds a new path to the list of current incomplete paths /// </summary> /// <param name="p">Path</param> public void AddPath(PotentialPath p) { if (!this._incompletePaths.Contains(p)) { this._incompletePaths.Add(p); } }
/// <summary> /// Evaluates the Path using the given Path Evaluation Context /// </summary> /// <param name="context">Path Evaluation Context</param> public void Evaluate(PathEvaluationContext context) { IEnumerable<Triple> ts; if (context.IsFirst) { //First thing firsts we'll set that the path is no longer at the first thing since we're the first thing! context.IsFirst = false; //We're the start of a Path if (context.PathStart.VariableName != null) { //Path starts from a Variable String var = context.PathStart.VariableName; if (context.SparqlContext.InputMultiset.ContainsVariable(var)) { //Path starts from a Variable for which we have existing values IEnumerable<INode> values = (from s in context.SparqlContext.InputMultiset.Sets where s.ContainsVariable(var) select s[var]).Distinct(); foreach (INode n in values) { if (context.IsReversed) { //If the Path is currently reversed then we'll look at triples with the given Predicate-Object pair ts = context.SparqlContext.Data.GetTriplesWithPredicateObject(this._predicate, n); } else { //For normal forward paths we'll look at triples with the given Subject-Predicate pair ts = context.SparqlContext.Data.GetTriplesWithSubjectPredicate(n, this._predicate); } //Bind path as appropriate foreach (Triple t in ts) { PotentialPath p; if (context.IsReversed) { p = new PotentialPath(n, t.Subject); } else { p = new PotentialPath(n, t.Object); } context.AddPath(p); } } } else { //Path starts from an as yet unbound Variable ts = context.SparqlContext.Data.GetTriplesWithPredicate(this._predicate); //Bind paths as appropriate foreach (Triple t in ts) { PotentialPath p; if (context.IsReversed) { p = new PotentialPath(t.Object, t.Subject); } else { p = new PotentialPath(t.Subject, t.Object); } context.AddPath(p); } } } else { //Path starts from a fixed value INode fixedSubj = ((NodeMatchPattern)context.PathStart).Node; if (context.IsReversed) { //If the Path is currently reversed then we'll look at triples with the given Predicate-Object pair ts = context.SparqlContext.Data.GetTriplesWithPredicateObject(this._predicate, fixedSubj); } else { //For normal forward paths we'll look at triples with the given Subject-Predicate pair ts = context.SparqlContext.Data.GetTriplesWithSubjectPredicate(fixedSubj, this._predicate); } //Map each Triple as a Path foreach (Triple t in ts) { PotentialPath p; if (context.IsReversed) { p = new PotentialPath(t.Object, fixedSubj); } else { p = new PotentialPath(fixedSubj, t.Object); } context.AddPath(p); } } } else { //We're not the start of a Path so we're continuing from a previous path //This means all paths must continue from the Current position of an incomplete path //If we are permitted to introduce new paths we can go ahead and do that here if (context.PermitsNewPaths) { //Introduce new paths based on the predicate at this stage ts = context.SparqlContext.Data.GetTriplesWithPredicate(this._predicate); foreach (Triple t in ts) { PotentialPath p; if (context.IsReversed) { p = new PotentialPath(t.Object, t.Object); p.Length = 0; } else { p = new PotentialPath(t.Subject, t.Subject); p.Length = 0; } context.AddPath(p); } context.PermitsNewPaths = false; } //If there are no incomplete paths we abort if (context.Paths.Count == 0) return; //For each incomplete path we attempt to extend the Path HashSet<PotentialPath> incomplete = new HashSet<PotentialPath>(); foreach (PotentialPath p in context.Paths) { //Ignore dead-end paths if (p.IsDeadEnd) continue; if (context.IsReversed) { ts = context.SparqlContext.Data.GetTriplesWithPredicateObject(this._predicate, p.Current); } else { ts = context.SparqlContext.Data.GetTriplesWithSubjectPredicate(p.Current, this._predicate); } //int c = 0; foreach (Triple t in ts) { PotentialPath p2; ; if (context.IsReversed) { p2 = new PotentialPath(p.Start, t.Subject); p2.Length = p.Length + 1; } else { p2 = new PotentialPath(p.Start, t.Object); p2.Length = p.Length + 1; } incomplete.Add(p2); } } //Add the newly found paths to the set of incomplete paths foreach (PotentialPath p in incomplete) { context.AddPath(p); } } //If we're the Last thing in the Path we can now mark any completed paths if (context.IsLast) { bool objVar = (context.PathEnd.VariableName != null); bool objVarBound = (objVar && context.SparqlContext.InputMultiset.ContainsVariable(context.PathEnd.VariableName)); foreach (PotentialPath p in context.Paths) { if (!p.IsDeadEnd && !p.IsComplete && !p.IsPartial) { if (objVar) { if (objVarBound) { //If the end of the Path is a previously bound variable then we do an accepts check if (context.PathEnd.Accepts(context.SparqlContext, p.Current)) { p.IsComplete = true; context.AddCompletePath(p); } else { //We can mark this path as partial (I think) since it itself can't be completed //but there's a possibility that it might lead to a completable path at a later point p.IsPartial = true; } } else { //If the end of the Path is an as yet unbound variable then any value is acceptable p.IsComplete = true; context.AddCompletePath(p); } } else { if (context.PathEnd.Accepts(context.SparqlContext, p.Current)) { //If the Path End accepts the current path end we can complete it p.IsComplete = true; context.AddCompletePath(p); } else { //We can mark this path as partial (I think) since it itself can't be completed //but there's a possibility that it might lead to a completable path at a later point p.IsPartial = true; } } } } if (context.CanAbortEarly) { if (context.CompletePaths.Any(p => context.PathStart.Accepts(context.SparqlContext, p.Start) && context.PathEnd.Accepts(context.SparqlContext, p.Current))) { throw new RdfQueryPathFoundException(); } } } }