Exemplo n.º 1
0
 public void RetainAll(ResSet set)
 {
     foreach (Resource r in new ArrayList(this))
     {
         if (!set.Contains(r))
         {
             Remove(r);
         }
     }
 }
Exemplo n.º 2
0
		private static bool MakeLeanMSG3(Store msg, ResSet predicates, StatementSink removed,
			ResSet nodesremoved, SyncPath path) {
			// The variable path has to be expanded by including the statements
			// connected to the variables on the frontier.  Statements
			// mentioning a variable node have already been considered.
			// The target of each such statement can be considered fixed
			// or variable. If a variable is considered fixed, the edge
			// must exist in the MSG substituting the variables for their
			// values.  If it's variable, it has to have at least one
			// match in the MSG but not as any of the variable nodes.
			// If all targets are considered fixed (and have matches),
			// then the variables so far (and their edges) can all be
			// removed and no more processing needs to be done.
			// There are (2^N)-1 other considerations.  For each of those,
			// the targets considered variables all become the new
			// frontier, and this is repeated. 
			
			// First, get a list of edges from the frontier that we
			// haven't considered yet.
			
			ArrayList alledges = new ArrayList();
			foreach (BNode b in path.FrontierVariables) {
				// Make sure all edges are kept because even the ones
				// to literals have to be removed when duplication is found.
				foreach (Statement s in msg.Select(new Statement(b, null, null)))
					alledges.Add(new Edge(true, b, s.Predicate, s.Object));
				foreach (Statement s in msg.Select(new Statement(null, null, b)))
					alledges.Add(new Edge(false, b, s.Predicate, s.Subject));
			}
			
			ArrayList newedges = new ArrayList();
			ResSet alltargets = new ResSet();
			ResSet fixabletargetsset = new ResSet(); // can be fixed
			ResSet variabletargetsset = new ResSet(); // must be variable
			foreach (Edge e in alledges) {
				if (path.Path.ContainsKey(e)) continue;
				path.Path[e] = e;
				
				// This checks if we can keep the target of this edge
				// fixed, given the variable mappings we have so far.
				bool isTargetFixable =
					msg.Contains(e.AsStatement().Replace(path.Mapping));

				// If the target of e is any of the following, we
				// can check immediately if the edge is supported
				// by the MSG under the variable mapping we have so far:
				//    a named node, literal, fixed node, or predicate
				//    a variable we've seen already
				// If it's not supported, this path fails.  If it is
				// supported, we're done with this edge.
				if (!(e.End is BNode)
					|| path.FixedNodes.Contains(e.End)
					|| predicates.Contains(e.End)
					|| path.VariableNodes.Contains(e.End)) {
					if (!isTargetFixable) return false;
					continue; // this edge is supported, so we can continue
				}
				
				// The target of e is a new BNode.
				// If this target is not fixable via this edge, it's
				// not fixable at all.
				
				if (!isTargetFixable) {
					fixabletargetsset.Remove(e.End);
					variabletargetsset.Add(e.End);
				}
				
				if (!alltargets.Contains(e.End)) {
					alltargets.Add(e.End);
					fixabletargetsset.Add(e.End);
				}
				
				newedges.Add(e);
			}
			
			// If all of the targets were fixable (trivially true also
			// if there simple were no new edges/targets), then we've reached
			// the end of this path.  We can immediately remove
			// the edges we've seen so far, under the variable mapping
			// we've chosen.
			if (variabletargetsset.Count == 0) {
				foreach (Edge e in path.Path.Keys) {
					Statement s = e.AsStatement();
					msg.Remove(s);
					if (removed != null) removed.Add(s);
				}
				foreach (Entity e in path.Mapping.Keys)
					nodesremoved.Add(e);
				return true;
			}
			
			// At this point, at least one target must be a variable
			// and we'll have to expand the path in that direction.
			// We might want to permute through the ways we can
			// take fixable nodes as either fixed or variable, but
			// we'll be greedy and assume everything fixable is
			// fixed and everything else is a variable.
			
			path.FixedNodes.AddRange(fixabletargetsset);
			path.VariableNodes.AddRange(variabletargetsset);

			// But we need to look at all the ways each variable target
			// can be mapped to a new value, which means intersecting
			// the possible matches for each relevant edge.
			Entity[] variables = variabletargetsset.ToEntityArray();
			ResSet[] values = new ResSet[variables.Length];
			Entity[][] values_array = new Entity[variables.Length][];
			int[] choices = new int[variables.Length];
			for (int i = 0; i < variables.Length; i++) {
				foreach (Edge e in newedges) {
					if (e.End != variables[i]) continue;
					
					// Get the possible values this edge allows
					Resource[] vr;
					if (e.Direction)
						vr = msg.SelectObjects((Entity)path.Mapping[e.Start], e.Predicate);
					else
						vr = msg.SelectSubjects(e.Predicate, (Entity)path.Mapping[e.Start]);
					
					// Filter out literals and any variables
					// on the path!  The two paths can't intersect
					// except at fixed nodes.
					ResSet v = new ResSet();
					foreach (Resource r in vr) {
						if (r is Literal) continue;
						if (path.Mapping.ContainsKey(r)) continue;
						v.Add(r);
					}
					
					// Intersect these with the values we have already.
					if (values[i] == null)
						values[i] = v;
					else
						values[i].RetainAll(v);
						
					// If no values are available for this variable,
					// we're totally done.
					if (values[i].Count == 0) return false;
				}
				
				choices[i] = values[i].Count;
				values_array[i] = values[i].ToEntityArray();
			}
			
			// Now we have to permute through the choice of values.
			// Make an array of the number of choices for each variable.
			Permutation p = new Permutation(choices);
			int[] pstate;
			while ((pstate = p.Next()) != null) {
				SyncPath newpath = new SyncPath();
				newpath.FixedNodes.AddRange(path.FixedNodes);
				newpath.VariableNodes.AddRange(path.VariableNodes);
				newpath.Mapping = (Hashtable)path.Mapping.Clone();
				newpath.Path = (Hashtable)path.Path.Clone();
				
				newpath.FrontierVariables = variabletargetsset;
				
				for (int i = 0; i < variables.Length; i++) {
					Entity value = values_array[i][pstate[i]];
					newpath.Mapping[variables[i]] = value;
					newpath.FixedNodes.Add(value);
				}

				if (MakeLeanMSG3(msg, predicates, removed,
					nodesremoved, newpath)) return true;
			}
			
			return false;
		}
Exemplo n.º 3
0
		public static void FindMSG(SelectableSource store, Entity node, StatementSink msg) {
			if (node.Uri != null) throw new ArgumentException("node must be anonymous");
			
			ResSet nodesSeen = new ResSet();
			ResSet nodesToAdd = new ResSet();
			
			nodesToAdd.Add(node);
			
			while (nodesToAdd.Count > 0) {
				ResSet nodes = nodesToAdd;
				nodesToAdd = new ResSet();
				
				Sink sink = new Sink(msg, nodesToAdd);
				foreach (Entity n in nodes) {
					if (nodesSeen.Contains(n)) continue;
					nodesSeen.Add(n);
					store.Select(new Statement(n, null, null, null), sink);
					store.Select(new Statement(null, n, null, null), sink);
					store.Select(new Statement(null, null, n, null), sink);
				}
			}
		}
Exemplo n.º 4
0
		private static void MakeLeanMSG(Store msg, ICollection bnodecollection, StatementSink removed) {
			// To make any graph lean, we try to eliminate duplicate
			// paths through the graph, where duplicate means we
			// take some subset of the bnodes and call them variables,
			// and we relabel them as other bnodes from the remaining
			// set (the fixed nodes).  But there are 2^N subsets of bnodes
			// we could choose as variables (N=number of bnodes), so we can't
			// reasonably iterate through them.
			
			// I'll make a simplifying assumption that bnode predicates
			// in the graph will be considered always fixed.
			// This lets us view the graph as actually a graph (with
			// nodes and edges), and then we can make the observation that
			// if variable node V is part of a subgraph that can be removed,
			// if V directly connects to fixed node F via an edge labeled P,
			// then F must connect to a fixed node G via an edge also
			// labeled P.  That is, we can start our search looking for
			// nodes that project two edges with the same label.
			
			// Also, we only want to consider contiguous 'paths' -- subsets
			// of the bnodes connected only through those nodes --
			// to see if there is another path in the MSG if we
			// map bnodes in the first path to nodes in the MSG.
			
			// So the strategy is to start at each node in the graph
			// and consider it fixed.  If it has two outgoing
			// edges with the same property and one terminates on a
			// bnode, this is the beginning of a possible pair
			// of redundant paths (the one with the bnode being
			// eliminable).
			
			// However, the path with the bnode
			// has to be incremented with all of that bnode's
			// outgoing edges.  The other path has to be
			// incremented in parallel, following the same predicates
			// to other nodes.  If that can't be done, then these
			// paths are not duplicates.  If the parallel predicates
			// terminate on the very same nodes, the bnode and its edges can
			// be removed.
			
			// From there, each of the nodes the bnode edges terminate on,
			// besides the initial node, can be considered fixed or
			// a variable.  If it's a variable it might be able to have
			// one of many possible values, but then the path has to
			// be expanded to include all of the outgoing edges for this
			// variable.
		
			// Ok, here we go.
			
			// If there is only one bnode in the MSG, then
			// there are no subgraphs to check.  That's nice.
			if (bnodecollection.Count == 1) return;
			
			// Remember which bnodes have been removed in
			// due course.
			ResSet nodesremoved = new ResSet();
			
			// Remember which nodes are predicates and can't
			// be considered variable.
			ResSet predicates = new ResSet();
			foreach (Statement s in msg.Select(Statement.All))
				predicates.Add(s.Predicate);
			
			// Start with each bnode to consider fixed.
			foreach (BNode b in bnodecollection) {
				if (nodesremoved.Contains(b)) continue;
				MakeLeanMSG2(msg, predicates, removed, nodesremoved, b);
			}
		}
Exemplo n.º 5
0
		private static void MakeLeanMSG2(Store msg, ResSet predicates, StatementSink removed,
			ResSet nodesremoved, BNode startingnode) {
			
			// Find every pair of two distinct outgoing edges from startingnode
			// with the same predicate, targeting entities only.
			
			MultiMap edges = new MultiMap();
			
			foreach (Statement s in msg.Select(new Statement(startingnode, null, null)))
				if (s.Object is Entity)
					edges.Put(new Edge(true, startingnode, s.Predicate, null), s.Object);
			foreach (Statement s in msg.Select(new Statement(null, null, startingnode)))
				edges.Put(new Edge(false, startingnode, s.Predicate, null), s.Subject);
			
			foreach (Edge e in edges.Keys) {
				// Make sure we have a distinct set of targets.
				ResSet targets_set = new ResSet();
				foreach (Entity r in edges.Get(e))
					targets_set.Add(r);
				if (targets_set.Count == 1) continue;
				
				IList targets = targets_set.ToEntityArray();
				
				// Take every pair of targets, provided
				// one is a bnode that can be a variable.
				for (int i = 0; i < targets.Count; i++) {
					if (!(targets[i] is BNode) || predicates.Contains((BNode)targets[i])) continue;
					if (nodesremoved.Contains((BNode)targets[i])) continue;
					for (int j = 0; j < targets.Count; j++) {
						if (i == j) continue;
						// Create a new synchronous-path object.
						SyncPath p = new SyncPath();
						p.FixedNodes.Add((Resource)targets[j]);
						p.FrontierVariables.Add((Resource)targets[i]);
						p.Mapping[targets[i]] = targets[j];
						p.Path[new Edge(e.Direction, e.Start, e.Predicate, (BNode)targets[i])] = p.Path;
						if (MakeLeanMSG3(msg, predicates, removed, nodesremoved, p))
							break; // the target was removed
					}
				}
			}
		}
Exemplo n.º 6
0
		static Entity[] GetClosure(Resource[] starts, Hashtable table) {
			ResSet ret = new ResSet();
			ResSet toadd = new ResSet(starts);
			while (toadd.Count > 0) {
				ResSet newadd = new ResSet();
				
				foreach (Resource e in toadd) {
					if (!(e is Entity)) continue;
					if (ret.Contains(e)) continue;
					ret.Add(e);
					if (table.ContainsKey(e))
						newadd.AddRange((ResSet)table[e]);
				}
				
				toadd.Clear();
				toadd.AddRange(newadd);
			}
			return ret.ToEntityArray();
		}
Exemplo n.º 7
0
		public void RetainAll(ResSet set) {
			foreach (Resource r in new ArrayList(this))
				if (!set.Contains(r))
					Remove(r);
		}
Exemplo n.º 8
0
        // The next few routines convert a set of axioms from a StatementSource
        // into a data structure of use for the algorithm, with Sequents and things.
        private static Hashtable RulesToCases(StatementSource rules)
        {
            Hashtable cases = new Hashtable();
            MemoryStore rules_store = new MemoryStore(rules);
            foreach (Statement p in rules_store) {
                if (p.Meta == Statement.DefaultMeta) {
                    if (p.Predicate == entLOGIMPLIES && p.Object is Entity) {
                        MemoryStore body = new MemoryStore();
                        MemoryStore head = new MemoryStore();

                        rules_store.Select(new Statement(null, null, null,  (Entity)p.Subject), new RemoveMeta(body));
                        rules_store.Select(new Statement(null, null, null,  (Entity)p.Object), new RemoveMeta(head));

                        // Any variables in the head not bound in the body represent existentially closed bnodes.
                        // (Euler's OWL test case does this. Wish they had used bnodes instead of vars...)
                        ResSet bodyvars = new ResSet();
                        foreach (Statement b in body) {
                            if (b.Subject is Variable) bodyvars.Add(b.Subject);
                            if (b.Predicate is Variable) bodyvars.Add(b.Predicate);
                            if (b.Object is Variable) bodyvars.Add(b.Object);
                        }
                        foreach (Entity v in head.GetEntities()) {
                            if (v is Variable && !bodyvars.Contains(v))
                                head.Replace(v, new BNode(((Variable)v).LocalName));
                        }

                        // Replace (...) lists in the body that are tied to the subjects
                        // of user predicates with callArgs objects.
                        Hashtable callArgs = new Hashtable();
                        CollectCallArgs(body, callArgs);

                        // Rules can't have more than one statement in their
                        // consequent.  The best we can do is break up
                        // the consequent into multiple rules.  (Since all head
                        // variables are bound in body, it's equivalent...?)
                        foreach (Statement h in head)
                            AddSequent(cases, new Sequent(h, body.ToArray(), callArgs));
                    } else {
                        AddSequent(cases, new Sequent(p, new Statement[0], null));
                    }
                }
            }

            return cases;
        }
Exemplo n.º 9
0
		static Entity[] GetClosure(Resource[] starts, Hashtable table, bool includeStarts) {
			ResSet ret = new ResSet();
			ResSet toadd = new ResSet(starts);
			bool firstRound = true;
			while (toadd.Count > 0) {
				ResSet newadd = new ResSet();
				
				foreach (Resource e in toadd) {
					if (!(e is Entity)) continue;
					if (ret.Contains(e)) continue;
					if (!(firstRound && !includeStarts)) ret.Add(e);
					if (table.ContainsKey(e))
						newadd.AddRange((ResSet)table[e]);
				}
				
				toadd.Clear();
				toadd.AddRange(newadd);
				firstRound = false;
			}
			return ret.ToEntityArray();
		}
		public void Query(Statement[] graph, QueryOptions options, QueryResultSink sink) {
			if (options.DistinguishedVariables != null && options.DistinguishedVariables.Count == 0)
				throw new ArgumentException("options.DistinguishedVariables cannot be an empty list.");
		
			StringBuilder query = new StringBuilder();
			
			query.Append("SELECT ");

			// Get a list of variables and map them to fresh names
			#if !DOTNET2
			Hashtable variableNames = new Hashtable();
			#else
			Dictionary<Variable,string> variableNames = new Dictionary<Variable,string>();
			#endif
			Hashtable variableNames2 = new Hashtable();
			foreach (Statement s in graph) {
				for (int j = 0; j < 3; j++) {
					Variable v = s.GetComponent(j) as Variable;
					if (v == null) continue;
					if (variableNames.ContainsKey(v)) continue;
					variableNames2["v" + variableNames.Count] = v;
					variableNames[v] = "?v" + variableNames.Count;
				}
			}
			
			// What variables will we select on?
			ArrayList selectedVars = new ArrayList();
			foreach (Variable v in
				options.DistinguishedVariables != null
					? options.DistinguishedVariables
					: variableNames.Keys) {
				if (!variableNames.ContainsKey(v)) continue; // in case distinguished variables list
															 // has more than what actually appears in query
				if (selectedVars.Contains(v)) continue; // don't select more than once
				query.Append(variableNames[v]);
				query.Append(' ');
				selectedVars.Add(v);
			}
			
			if (selectedVars.Count == 0) {
				if (options.DistinguishedVariables == null)
					throw new ArgumentException("There were no variables in the query.");
				else
					throw new ArgumentException("None of the variables in the query were distinguished.");
			}
			
			// Bnodes are not allowed here -- we can't query on them.
			foreach (Statement s in graph) {
				for (int j = 0; j < 3; j++) {
					if (s.GetComponent(j) is BNode && !(s.GetComponent(j) is Variable)) {
						Variable[] varArray = (Variable[])selectedVars.ToArray(typeof(Variable));
						sink.Init(varArray);
						sink.Finished();
						return;
					}
				}
			}
			
			// Build the graph pattern.
			query.Append("WHERE {\n");
			
			ResSet firstVarUse = new ResSet();
			foreach (Statement s in graph) {
				for (int j = 0; j < 3; j++) {
					Resource r = s.GetComponent(j);
					query.Append(S(r, r is Variable && variableNames.ContainsKey((Variable)r) ? (string)variableNames[(Variable)r] : null));
					query.Append(" ");
				}
				query.Append(" . \n");
				if (options.VariableKnownValues != null) {
					for (int j = 0; j < 3; j++) {
						Resource r = s.GetComponent(j);
						if (firstVarUse.Contains(r)) continue;
						firstVarUse.Add(r);
						if (r is Variable && variableNames.ContainsKey((Variable)r) &&
						#if !DOTNET2
						options.VariableKnownValues.Contains(r)
						#else
						options.VariableKnownValues.ContainsKey((Variable)r)
						#endif
						)
							query.Append(SL(options.VariableKnownValues[(Variable)r], (string)variableNames[(Variable)r], true));
					}
				}
				// And what about meta...?
			}
			
			query.Append("}");
			
			if (options.Limit > 0) {
				query.Append(" LIMIT ");
				query.Append(options.Limit);
			}
			
			Load(query.ToString(), new QueryResultsWrapper(sink, variableNames2));
		}