Пример #1
0
 public Enumerator(StatementMap host)
 {
     this.host = host;
     stamp     = host.modificationCount;
     size      = host.table.Length;
     Reset();
 }
Пример #2
0
            public HashValues(StatementMap host)
            {
                if (host == null)
                {
                    throw new ArgumentNullException();
                }

                this.host = host;
            }
Пример #3
0
 public DistinctStatementsSink(StatementSink sink, bool resetMeta)
 {
     this.sink      = sink;
     hash           = new StatementMap();
     this.resetMeta = resetMeta;
 }
Пример #4
0
			public HashValues (StatementMap host) {
				if (host == null)
					throw new ArgumentNullException ();

				this.host = host;
			}
Пример #5
0
			public Enumerator (StatementMap host) {
				this.host = host;
				stamp = host.modificationCount;
				size = host.table.Length;
				Reset ();
			}
Пример #6
0
		public DistinctStatementsSink(StatementSink sink, bool resetMeta) {
			this.sink = sink;
			hash = new StatementMap();
			this.resetMeta = resetMeta;
		}
Пример #7
0
        private static ArrayList prove(Hashtable cases, SelectableSource world, Statement[] goal, int maxNumberOfSteps)
        {
            // This is the main routine from euler.js.

            // cases: Resource (predicate) => IList of Sequent

            if (world != null) // cache our queries to the world, if a world is provided
                world = new SemWeb.Stores.CachedSource(world);

            StatementMap cached_subproofs = new StatementMap();

            // Create the queue and add the first item.
            ArrayList queue = new ArrayList();
            {
                QueueItem start = new QueueItem();
                start.env = new Hashtable();
                start.rule = new Sequent(Statement.All, goal, null);
                start.src = null;
                start.ind = 0;
                start.parent = null;
                start.ground = new ArrayList();
                queue.Add(start);
                if (Debug) Console.Error.WriteLine("Euler: Queue: " + start);
            }

            // The evidence array holds the results of this proof.
            ArrayList evidence = new ArrayList();

            // Track how many steps we take to not go over the limit.
            int step = 0;

            // Process the queue until it's empty or we reach our step limit.
            while (queue.Count > 0) {
                // deal with the QueueItem at the top of the queue
                QueueItem c = (QueueItem)queue[queue.Count-1];
                queue.RemoveAt(queue.Count-1);
                ArrayList g = new ArrayList(c.ground);

                // have we done too much?
                step++;
                if (maxNumberOfSteps != -1 && step >= maxNumberOfSteps) {
                    if (Debug) Console.Error.WriteLine("Euler: Maximum number of steps exceeded.  Giving up.");
                    return null;
                }

                // if each statement in the body of the sequent has been proved
                if (c.ind == c.rule.body.Length) {
                    // if this is the top-level sequent being proved; we've found a complete evidence for the goal
                    if (c.parent == null) {
                        EvidenceItem ev = new EvidenceItem();
                        ev.head = new Statement[c.rule.body.Length];
                        bool canRepresentHead = true;
                        for (int i = 0; i < c.rule.body.Length; i++) {
                            ev.head[i] = evaluate(c.rule.body[i], c.env);
                            if (ev.head[i].AnyNull) // can't represent it: literal in subject position, for instance
                                canRepresentHead = false;
                        }

                        ev.body = c.ground;
                        ev.env = c.env;

                        if (Debug) Console.Error.WriteLine("Euler: Found Evidence: " + ev);

                        if (!canRepresentHead)
                            continue;

                        evidence.Add(ev);

                    // this is a subproof of something; whatever it is a subgroup for can
                    // be incremented
                    } else {
                        // if the rule had no body, it was just an axiom and we represent that with Ground
                        if (c.rule.body.Length != 0) g.Add(new Ground(c.rule, c.env));

                        // advance the parent being proved and put the advanced
                        // parent into the queue; unify the parent variable assignments
                        // with this one's
                        QueueItem r = new QueueItem();
                        r.rule = c.parent.rule;
                        r.src = c.parent.src;
                        r.ind = c.parent.ind;
                        r.parent = c.parent.parent;
                        r.env = (Hashtable)c.parent.env.Clone();
                        r.ground = g;
                        unify(c.rule.head, c.env, r.rule.body[r.ind], r.env, true);
                        r.ind++;
                        queue.Add(r);
                        if (Debug) Console.Error.WriteLine("Euler: Queue Advancement: " + r);

                        // The number of live children for this parent is decremented since we are
                        // done with this subproof, but we store the result for later.
                        if (c.parent.solutions == null)
                            c.parent.solutions = new StatementList();
                        c.parent.solutions.Add(evaluate(r.rule.body[r.ind-1], r.env));
                        decrementLife(c.parent, cached_subproofs);
                    }

                // this sequent still has parts of the body left to be proved; try to
                // find evidence for the next statement in the body, and if we find
                // evidence, queue up that evidence
                } else {
                    // this is the next part of the body that we need to try to prove
                    Statement t = c.rule.body[c.ind];

                    // Try to process this predicate with a user-provided custom
                    // function that resolves things like mathematical relations.
                    // euler.js provides similar functionality, but the system
                    // of user predicates is completely different here.
                    RdfRelation b = FindUserPredicate(t.Predicate);
                    if (b != null) {
                        Resource[] args;
                        Variable[] unifyResult;
                        Resource value = evaluate(t.Object, c.env);

                        if (!c.rule.callArgs.ContainsKey(t.Subject)) {
                            // The array of arguments to this relation is just the subject of the triple itself
                            args = new Resource[] { evaluate(t.Subject, c.env) };
                            unifyResult = new Variable[1];
                            if (t.Subject is Variable) unifyResult[0] = (Variable)t.Subject;

                        } else {
                            // The array of arguments to this relation comes from a pre-grouped arg list.
                            args = (Resource[])((ICloneable)c.rule.callArgs[t.Subject]).Clone();
                            unifyResult = new Variable[args.Length];

                            for (int i = 0; i < args.Length; i++) {
                                if (args[i] is Variable) {
                                    unifyResult[i] = (Variable)args[i];
                                    args[i] = evaluate(args[i], c.env);
                                }
                            }
                        }

                        // Run the user relation on the array of arguments (subject) and on the object.
                        if (b.Evaluate(args, ref value)) {
                            // If it succeeds, we press on.

                            // The user predicate may update the 'value' variable and the argument
                            // list array, and so we want to unify any variables in the subject
                            // or object of this user predicate with the values given to us
                            // by the user predicate.
                            Hashtable newenv = (Hashtable)c.env.Clone();
                            if (t.Object is Variable) unify(value, null, t.Object, newenv, true);
                            for (int i = 0; i < args.Length; i++)
                                if (unifyResult[i] != null)
                                    unify(args[i], null, unifyResult[i], newenv, true);

                            Statement grnd = evaluate(t, newenv);
                            if (grnd != Statement.All) // sometimes not representable, like if literal as subject
                                g.Add(new Ground(new Sequent(grnd, new Statement[0], null), new Hashtable()));

                            QueueItem r = new QueueItem();
                            r.rule = c.rule;
                            r.src = c.src;
                            r.ind = c.ind;
                            r.parent = c.parent;
                            r.env = newenv;
                            r.ground = g;
                            r.ind++;
                            queue.Add(r);

                            // Note: Since we are putting something back in for c, we don't touch the life counter on the parent.

                        } else {
                            // If the predicate fails, decrement the life of the parent.
                            if (c.parent != null)
                                decrementLife(c.parent, cached_subproofs);
                        }
                        continue;
                    }

                    // t can be proved either by the use of a rule
                    // or if t literally exists in the world

                    Statement t_resolved = evaluate(t, c.env);

                    // If resolving this statement requires putting a literal in subject or predicate position, we
                    // can't prove it.
                    if (t_resolved == Statement.All) {
                        if (c.parent != null)
                            decrementLife(c.parent, cached_subproofs);
                        continue;
                    }

                    ArrayList tcases = new ArrayList();

                    // See if we have already tried to prove this.
                    if (cached_subproofs.ContainsKey(t_resolved)) {
                        StatementList cached_solutions = (StatementList)cached_subproofs[t_resolved];
                        if (cached_solutions == null) {
                            if (Debug) Console.Error.WriteLine("Euler: Dropping queue item because we have already failed to prove it: " + t_resolved);
                        } else {
                            foreach (Statement s in cached_solutions) {
                                if (Debug) Console.Error.WriteLine("Euler: Using Cached Axiom:  " + s);
                                Sequent seq = new Sequent(s);
                                tcases.Add(seq);
                            }
                        }
                    } else {
                        // get all of the rules that apply to the predicate in question
                        if (t_resolved.Predicate != null && cases.ContainsKey(t_resolved.Predicate))
                            tcases.AddRange((IList)cases[t_resolved.Predicate]);

                        if (cases.ContainsKey("WILDCARD"))
                            tcases.AddRange((IList)cases["WILDCARD"]);

                        // if t has no unbound variables and we've matched something from
                        // the axioms, don't bother looking at the world, and don't bother
                        // proving it any other way than by the axiom.
                        bool lookAtWorld = true;
                        foreach (Sequent seq in tcases) {
                            if (seq.body.Length == 0 && seq.head == t_resolved) {
                                lookAtWorld = false;
                                tcases.Clear();
                                tcases.Add(seq);
                                break;
                            }
                        }

                        // if there is a seprate world, get all of the world
                        // statements that witness t
                        if (world != null && lookAtWorld) {
                            MemoryStore w = new MemoryStore();

                            if (Debug) Console.Error.WriteLine("Running " + c);
                            if (Debug) Console.Error.WriteLine("Euler: Ask World: " + t_resolved);
                            world.Select(t_resolved, w);
                            foreach (Statement s in w) {
                                if (Debug) Console.Error.WriteLine("Euler: World Select Response:  " + s);
                                Sequent seq = new Sequent(s);
                                tcases.Add(seq);
                            }
                        }
                    }

                    // If there is no evidence or potential evidence (i.e. rules)
                    // for t, then we will dump this QueueItem by not queuing any
                    // subproofs.

                    // Otherwise we try each piece of evidence in turn.
                    foreach (Sequent rl in tcases) {
                        ArrayList g2 = (ArrayList)c.ground.Clone();
                        if (rl.body.Length == 0) g2.Add(new Ground(rl, new Hashtable()));

                        QueueItem r = new QueueItem();
                        r.rule = rl;
                        r.src = rl;
                        r.ind = 0;
                        r.parent = c;
                        r.env = new Hashtable();
                        r.ground = g2;

                        if (unify(t, c.env, rl.head, r.env, true)) {
                            QueueItem ep = c;  // euler path
                         	while ((ep = ep.parent) != null)
                          		if (ep.src == c.src && unify(ep.rule.head, ep.env, c.rule.head, c.env, false))
                          			break;
                         	if (ep == null) {
                                // It is better for caching subproofs to work an entire proof out before
                                // going on, which means we want to put the new queue item at the
                                // top of the stack.
                         		queue.Add(r);
                                c.liveChildren++;
                         		if (Debug) Console.Error.WriteLine("Euler: Queue from Axiom: " + r);
                         	}
                        }
                    }

                    // If we did not add anything back into the queue for this item, then
                    // we decrement the life of the parent.
                    if (c.liveChildren == 0 && c.parent != null)
                        decrementLife(c.parent, cached_subproofs);
                }
            }

            return evidence;
        }
Пример #8
0
 private static void decrementLife(QueueItem q, StatementMap cached_subproofs)
 {
     q.liveChildren--;
     if (q.liveChildren == 0) {
         Statement t = evaluate(q.rule.body[q.ind], q.env);
         cached_subproofs[t] = q.solutions;
         if (Debug && q.solutions == null) Console.Error.WriteLine("Euler: Died: " + q);
     }
 }