public PartListImpl ParseBody(Tokeniser tk, string mt)
        {
            // Body -> Term {, Term...}

            PartListImpl p = new PartListImpl();
            var          i = 0;

            Term t;

            while ((t = (Term)ParseTerm(tk, mt)) != null)
            {
                p.AddPart(t);
                i++;
                if (tk.current != ",")
                {
                    break;
                }
                tk.consume();
            }

            if (i == 0)
            {
                return(null);
            }
            return(p);
        }
        public ProveResult TripleQuery(Term thisTerm, PartListImpl goalList, PEnv environment, PDB db, int level, reportDelegate reportFunction)
        {
            // bagof(Term, ConditionTerm, ReturnList)
            //  PartList goalList = (PartList)goalIn;

            Part collect0 = value((Part)thisTerm.ArgList[0], environment);
            Part subgoal  = value((Part)thisTerm.ArgList[1], environment);
            Part into     = value((Part)thisTerm.ArgList[2], environment);

            Part collect = renameVariables(collect0, level, thisTerm);
            //var newGoal = new Term(subgoal.name, renameVariables(subgoal.ArgList, level, thisTerm));
            Term newGoal = new Term(subgoal.fname, false,
                                    (PartListImpl)renameVariables(((PartListImpl)subgoal), level, thisTerm));

            newGoal.parent = thisTerm;

            //var newGoals = [];
            //newGoals[0] = newGoal;
            PartListImpl newGoals = new PartListImpl();

            newGoals.AddPart(newGoal);

            // Prove this subgoal, collecting up the environments...
            PartListImpl anslist = new PartListImpl();

            anslist.renumber = -1;
            var ret = prove(newGoals, environment, db, level + 1, BagOfCollectFunction(collect, anslist));

            // Turn anslist into a proper list and unify with 'into'

            // optional here: nil anslist -> fail?
            Part answers = Atom.FromSource(FUNCTOR_NIL);

            /*
             * print("Debug: anslist = [");
             *  for (var j = 0; j < anslist.length; j++) {
             *      anslist[j].print();
             *      print(", ");
             *  }
             * print("]\n");
             */

            for (int i = anslist.Arity; i > 0; i--)
            {
                answers = MakeList(anslist.ArgList[i - 1], answers);
            }

            //print("Debug: unifying "); into.print(); print(" with "); answers.print(); print("\n");
            var env2 = unify(into, answers, environment);

            if (env2 == null)
            {
                //print("Debug: bagof cannot unify anslist with "); into.print(); print(", failing\n");
                return(null);
            }

            // Just prove the rest of the goallist, recursively.
            return(prove(goalList, env2, db, level + 1, reportFunction));
        }
            public static bool AddRdfList(PartListImpl parts, INode node, int argNum, INode obj, Triple triple,
                                          IGraph listResolves)
            {
                if (parts.Count + 1 == argNum)
                {
                    bool a = AddRdfList(parts, obj, -1, null, triple, listResolves);
                    bool b = AddRdfList(parts, node, -1, null, triple, listResolves);
                    return(a && b);
                }
                switch (node.NodeType)
                {
                case NodeType.Uri:
                case NodeType.Literal:
                    parts.AddPart(Atom.MakeNodeAtom(node));
                    return(true);

                case NodeType.Variable:
                    parts.AddPart(new Variable(node.ToString().Substring(1)));
                    return(true);

                case NodeType.Blank:
                {
                    INode f, r;
                    if (GetRdfList(node, listResolves, out f, out r, triple))
                    {
                        bool a = AddRdfList(parts, f, argNum, obj, triple, listResolves);
                        bool b = AddRdfList(parts, r, argNum, obj, triple, listResolves);
                        return(a && b);
                    }
                }
                    parts.AddPart(Atom.MakeNodeAtom(node));
                    return(foundNodeMoreThanTriple(listResolves, node, triple));

                // case NodeType.GraphLiteral:
                //   break;
                default:
                    Warn("cant intern " + node);
                    return(false);

                    throw new ArgumentOutOfRangeException();
                }
            }
        static public PartListImpl ParseConjuncts(Tokeniser tk, string mt, string requiredEnd, string sep, bool eofReturnsPart)
        {
            // Body -> Term {, Term...}

            PartListImpl p = new PartListImpl();
            var          i = 0;

            while (true)
            {
                if (tk.current == requiredEnd)
                {
                    tk.consume();
                    break;
                }
                if (tk.current == "eof")
                {
                    if (!eofReturnsPart)
                    {
                        prolog_reader_debug("read EOF " + tk);
                        return(null);
                    }
                    break;
                }
                if (tk.current == sep)
                {
                    tk.consume();
                    continue;
                }
                Part t = ParsePart(tk, mt);
                if (t == null)
                {
                    prolog_reader_debug("cant read Conjuct item " + tk);
                    return(null);
                }
                p.AddPart(t);
                i++;
            }

            if (i == 0)
            {
                prolog_reader_debug("no items read " + tk);
                return(null);
            }
            return(p);
        }
 // Aux function: return the reportFunction to use with a bagof subgoal
 public reportDelegate IstQueryCollectFunction(Part collect, PartListImpl anslist)
 {
     return(delegate(PEnv env)
     {
         /*
          * print("DEBUG: solution in bagof/3 found...\n");
          * print("Value of collection term ");
          * collect.print();
          * print(" in this environment = ");
          * (value(collect, env)).print();
          * print("\n");
          * printEnv(env);
          */
         // Rename this appropriately and throw it into anslist
         anslist.AddPart(renameVariables(value(collect, env), anslist.renumber--, null));
         return true;
     });
 }