private List <Problem <Hypergraph.EdgeAnnotation> > GenerateBackwardProblems(List <GroundedClause> goalClauses,
                                                                                     Pebbler.HyperEdgeMultiMap <Hypergraph.EdgeAnnotation> edgeDatabase)
        {
//            System.Diagnostics.Debug.WriteLine("Backward");

            List <int> clauseIndices = AcquireGoalIndices(goalClauses);

            // The resultant structure of problems; graph size dictates associated array size in hashMap; number of givens is a limiting factor the size of problems
            // Problem generation limits the number of givens in BACKWARD problems to 4 (or the constant in the HashMap structure)
            ProblemHashMap <Hypergraph.EdgeAnnotation> problems = new ProblemHashMap <Hypergraph.EdgeAnnotation>(edgeDatabase, graph.vertices.Count);

            // Generate all the problems based on the node indices
            foreach (int goalNode in clauseIndices)
            {
                if (Utilities.PROBLEM_GEN_DEBUG)
                {
                    System.Diagnostics.Debug.WriteLine("Template node; will generate problems (" + goalNode + "): " + graph.vertices[goalNode].data.ToString());
                }

                pathGenerator.GenerateProblemsUsingBackwardPathToLeaves(problems, edgeDatabase, goalNode);
            }

            // Filter backward problems so that only problems with goal being the original figure givens persist.
            return(FilterBackwardProblems(clauseIndices, FilterForMinimalAndRedundantProblems(problems.GetAll())));
        }
Example #2
0
        //
        // COMPELTE POWERSET implementation
        //
        // Time consuming, but complete.
        //

        //
        // From this node, generate all problems backward.
        // Do so by generating simple problems first (in a depth-first manner)
        //
        private List <Problem <Hypergraph.EdgeAnnotation> > GenerateAllProblemsFrom(ProblemHashMap <Hypergraph.EdgeAnnotation> memoizedProblems,
                                                                                    HyperEdgeMultiMap <Hypergraph.EdgeAnnotation> edgeDatabase, int node)
        {
            // If we have already generated problems, no need to regenerate
            if (memoizedProblems.HasNodeBeenGenerated(node))
            {
                return(memoizedProblems.Get(node));
            }

            // For all edges, create base problems and add them all to the database
            List <PebblerHyperEdge <Hypergraph.EdgeAnnotation> > forwardEdges = edgeDatabase.GetBasedOnGoal(node);

            // If there are no edges, this is a 'root' node (has no predecessors)
            if (forwardEdges == null || !forwardEdges.Any())
            {
                // We've successfully generated all the problems for this node: zero problems
                memoizedProblems.SetGenerated(node);
                return(new List <Problem <Hypergraph.EdgeAnnotation> >());
            }

            //
            // Create all the base problems consisting of only one edge and add to the database
            List <Problem <Hypergraph.EdgeAnnotation> > baseProblems = new List <Problem <Hypergraph.EdgeAnnotation> >();

            foreach (PebblerHyperEdge <Hypergraph.EdgeAnnotation> edge in forwardEdges)
            {
                baseProblems.Add(new Problem <Hypergraph.EdgeAnnotation>(edge));
            }
            memoizedProblems.PutUnchecked(baseProblems);

            // For all of the base problems, generate backward
            foreach (Problem <Hypergraph.EdgeAnnotation> baseProblem in baseProblems)
            {
                GenerateAllProblemsFromSingleEdge(memoizedProblems, edgeDatabase, baseProblem);
            }

            // We've successfully generated all the problems for this node
            memoizedProblems.SetGenerated(node);

            // Return all the generated problems
            return(memoizedProblems.Get(node));
        }
Example #3
0
        //
        // For all given nodes in this problem, generate the single maximal problem
        //
        // This is done is a convluted way to speed up execution since we need to combine in the size of the powerset of cardinality of givens
        //
        private void GenerateMaximalProblemFromSingleEdge(ProblemHashMap <Hypergraph.EdgeAnnotation> memoizedProblems,
                                                          HyperEdgeMultiMap <Hypergraph.EdgeAnnotation> edgeDatabase,
                                                          Problem <Hypergraph.EdgeAnnotation> baseProblem)
        {
            // Create all simple problems by pursuing only a single path backward in the givens: append
            // all problems from a given to the base problem
            //
            //           |
            //           v
            //         given    __
            //           |        |
            //           v        |  baseProblem
            //          goal    __|
            //
            // Acquire all of the problems for the singleton sets of the powerset for all of the givens of this problem
            List <Problem <Hypergraph.EdgeAnnotation> >[] singletonMapToNewProblems      = new List <Problem <Hypergraph.EdgeAnnotation> > [baseProblem.givens.Count];
            List <Problem <Hypergraph.EdgeAnnotation> >[] singletonMapToOriginalProblems = new List <Problem <Hypergraph.EdgeAnnotation> > [baseProblem.givens.Count];
            bool generatedNewProblems = false;

            for (int g = 0; g < baseProblem.givens.Count; g++)
            {
                // Acquire the original problems and save them
                singletonMapToOriginalProblems[g] = GenerateAllMaximalProblemsFrom(memoizedProblems, edgeDatabase, baseProblem.givens[g]);
                if (singletonMapToOriginalProblems[g] == null)
                {
                    singletonMapToOriginalProblems[g] = new List <Problem <Hypergraph.EdgeAnnotation> >();
                }

                // Using the original problems, append them to the base problem
                singletonMapToNewProblems[g] = new List <Problem <Hypergraph.EdgeAnnotation> >();

                // Append all of these given problems to the base problem
                foreach (Problem <Hypergraph.EdgeAnnotation> problem in singletonMapToOriginalProblems[g])
                {
                    Problem <Hypergraph.EdgeAnnotation> baseProblemCopy = new Problem <Hypergraph.EdgeAnnotation>(baseProblem);
                    baseProblemCopy.Append(graph, edgeDatabase, problem);
                    //memoizedProblems.Put(baseProblemCopy);
                    singletonMapToNewProblems[g].Add(baseProblemCopy);
                    generatedNewProblems = true;
                }
            }

            if (baseProblem.goal == 98)
            {
                //Debug.WriteLine("98NO-OP");
            }

            // If we did not perform any appending, we have reached a maximal situation
            // Add the maximal problem to the database
            if (!generatedNewProblems)
            {
                // Determine suppression now to mitigate number of problems added
                baseProblem.DetermineSuppressedGivens(graph);
                memoizedProblems.Put(baseProblem);
                return;
            }

            //
            // Stitch together all of the possible combinations of maximal problems
            //
            //    |  |        |
            //    |  |        |
            //    v  v        v
            //   g_1 g_2 ... g_n   __
            //           |           |  baseProblem
            //           v           |
            //         target      __|
            //
            //
            // We are looking for the maximal set of problems; therefore, we don't need all combinations.
            // What we do require is the combining of all generated problems with the base problem.
            //
            // Find all the sets of populated new problems
            List <int> populatedIndices = new List <int>();

            for (int index = 0; index < singletonMapToNewProblems.Length; index++)
            {
                if (singletonMapToNewProblems[index].Any())
                {
                    populatedIndices.Add(index);
                }
            }

            List <Problem <Hypergraph.EdgeAnnotation> > maximalProblems = new List <Problem <Hypergraph.EdgeAnnotation> >(singletonMapToNewProblems[populatedIndices[0]]);

            populatedIndices.RemoveAt(0);
            foreach (int index in populatedIndices)
            {
                //int count = 0;
                List <Problem <Hypergraph.EdgeAnnotation> > tmpMaximalProbs = new List <Problem <Hypergraph.EdgeAnnotation> >();
                foreach (Problem <Hypergraph.EdgeAnnotation> singleton in singletonMapToOriginalProblems[index])
                {
                    foreach (Problem <Hypergraph.EdgeAnnotation> problem in maximalProblems)
                    {
                        //if (baseProblem.goal == 98)
                        //{
                        //    Debug.WriteLine(count++);
                        //}

                        Problem <Hypergraph.EdgeAnnotation> problemCopy = new Problem <Hypergraph.EdgeAnnotation>(problem);
                        // It is possible for a problem to have been created which deduced further information with an additional edge;
                        // that is, a given node was pushed into the path of the problem. Hence, no need to append in this situation
                        if (problem.givens.Contains(singleton.goal))
                        {
                            problemCopy.Append(graph, edgeDatabase, singleton);
                        }
                        tmpMaximalProbs.Add(problemCopy);
                    }
                }
                maximalProblems = tmpMaximalProbs;
            }

            // Add all the maximal problems to the database
            foreach (Problem <Hypergraph.EdgeAnnotation> problem in maximalProblems)
            {
                // Determine suppression now to mitigate number of problems added
                problem.DetermineSuppressedGivens(graph);
                memoizedProblems.Put(problem);
            }
        }
Example #4
0
        //
        // For all given nodes in this problem, generate all problems
        //
        // This is done is a convluted way to speed up execution since we need to combine in the size of the powerset of cardinality of givens
        //
        private void GenerateAllProblemsFromSingleEdge(ProblemHashMap <Hypergraph.EdgeAnnotation> memoizedProblems,
                                                       HyperEdgeMultiMap <Hypergraph.EdgeAnnotation> edgeDatabase,
                                                       Problem <Hypergraph.EdgeAnnotation> baseProblem)
        {
            // Create all simple problems by pursuing only a single path backward in the givens: append
            // all problems from a given to the base problem
            //
            //           |
            //           v
            //         given    __
            //           |        |
            //           v        |  baseProblem
            //          goal    __|
            //
            // Acquire all of the problems for the singleton sets of the powerset for all of the givens of this problem
            List <Problem <Hypergraph.EdgeAnnotation> >[] singletonMapToNewProblems      = new List <Problem <Hypergraph.EdgeAnnotation> > [baseProblem.givens.Count];
            List <Problem <Hypergraph.EdgeAnnotation> >[] singletonMapToOriginalProblems = new List <Problem <Hypergraph.EdgeAnnotation> > [baseProblem.givens.Count];
            for (int g = 0; g < baseProblem.givens.Count; g++)
            {
                // Acquire the original problems and save them
                singletonMapToOriginalProblems[g] = GenerateAllProblemsFrom(memoizedProblems, edgeDatabase, baseProblem.givens[g]);
                if (singletonMapToOriginalProblems[g] == null)
                {
                    singletonMapToOriginalProblems[g] = new List <Problem <Hypergraph.EdgeAnnotation> >();
                }

                // Using the original problems, append them to the base problem
                singletonMapToNewProblems[g] = new List <Problem <Hypergraph.EdgeAnnotation> >();

                // Append all of these given problems to the base problem
                foreach (Problem <Hypergraph.EdgeAnnotation> problem in singletonMapToOriginalProblems[g])
                {
                    Problem <Hypergraph.EdgeAnnotation> baseProblemCopy = new Problem <Hypergraph.EdgeAnnotation>(baseProblem);
                    baseProblemCopy.Append(graph, edgeDatabase, problem);
                    memoizedProblems.Put(baseProblemCopy);
                    singletonMapToNewProblems[g].Add(baseProblemCopy);
                }
            }

            // If there was only 1 given, we need to perform a powerset combining
            if (baseProblem.givens.Count == 1)
            {
                return;
            }

            //
            // Stitch together all of the possible combinations of problems that will result;
            // note this is a POWERSET construction of all possible problems; hence, note exponential explosion in number of problems
            //
            //    |   |
            //    |   |
            //    v   v
            //   g_1 g_2 ... g_n   __
            //           |           |  baseProblem
            //           v           |
            //         target      __|
            //
            //    |           |
            //    |           |
            //    v           v
            //   g_1 g_2 ... g_n   __
            //           |           |  baseProblem
            //           v           |
            //         target      __|
            //
            //    |  |        |
            //    |  |        |
            //    v  v        v
            //   g_1 g_2 ... g_n   __
            //           |           |  baseProblem
            //           v           |
            //         target      __|
            //
            // Acquire an encoded list of subsets: the powerset for the number of givens in this problem
            List <string> powerset = Utilities.ConstructPowerSetStringsWithNoEmpty(baseProblem.givens.Count, baseProblem.givens.Count); // <-- We avoid generating singleton sets

            // Maps a subset string representation (from the powerset) to the list of problems that it results in.
            Dictionary <string, List <Problem <Hypergraph.EdgeAnnotation> > > powersetMapToProblems = new Dictionary <string, List <Problem <Hypergraph.EdgeAnnotation> > >(powerset.Count);

            //
            // For every combination of possible problems (a subset of the powerset), we combine problems
            //
            // Note, the Utilities generated the powerset in the specific sorted ordering of lower cardinality sets first (also values in subset are increasing)
            // So a typical subset string is given by 012 or 023
            foreach (string subset in powerset)
            {
                // Break the subset string into its constituent elements: <Arbitrary subset, singleton>
                KeyValuePair <string, int> splitSubset = Utilities.SplitStringIntoKnownToProcess(subset);

                // Subset Problems; given the subset {012}: {01}
                List <Problem <Hypergraph.EdgeAnnotation> > subsetProblems;
                if (!powersetMapToProblems.TryGetValue(splitSubset.Key, out subsetProblems))
                {
                    // Use the singleton list; ASCII conversion of char to int
                    subsetProblems = singletonMapToNewProblems[Convert.ToInt32(splitSubset.Key)];
                }

                // Singleton tails; given the subset {012}: {2}
                List <Problem <Hypergraph.EdgeAnnotation> > singletonProblems = singletonMapToOriginalProblems[splitSubset.Value];

                // Combine the precomputed powerset subset (.Key) guiding the appending of the singleton (.Value) problems
                List <Problem <Hypergraph.EdgeAnnotation> > combinedSubsetProblems = new List <Problem <Hypergraph.EdgeAnnotation> >();
                foreach (Problem <Hypergraph.EdgeAnnotation> subsetProblem in subsetProblems)
                {
                    foreach (Problem <Hypergraph.EdgeAnnotation> singletonProb in singletonProblems)
                    {
                        // It is possible for a problem to have been created which deduced further information with an additional edge;
                        // that is, a given node was pushed into the path of the problem. Hence, no need to append in this situation
                        if (subsetProblem.givens.Contains(singletonProb.goal))
                        {
                            // Combine the two problems and record
                            Problem <Hypergraph.EdgeAnnotation> subsetProblemCopy = new Problem <Hypergraph.EdgeAnnotation>(subsetProblem);
                            subsetProblemCopy.Append(graph, edgeDatabase, singletonProb);
                            memoizedProblems.Put(subsetProblemCopy);
                            combinedSubsetProblems.Add(subsetProblemCopy);
                        }
                    }
                }

                // We have calculated the problems for this subset, keep track of them
                powersetMapToProblems.Add(subset, combinedSubsetProblems);
            }
        }
Example #5
0
 //
 // Given a start node, construct a path using reachability analysis to construct a path from start template node back to leaves.
 // Forward problems are generated by following forward edges in reverse
 //
 //                                      A multimap of all pebbled edges (from pebbling)
 public void GenerateProblemsUsingBackwardPathToLeaves(ProblemHashMap <Hypergraph.EdgeAnnotation> memoizedProblems,
                                                       HyperEdgeMultiMap <Hypergraph.EdgeAnnotation> edgeDatabase, int goalNode)
 {
     // Although this returns the set of problems, we can still acquire them through the ProblemHashMap
     GenerateAllMaximalProblemsFrom(memoizedProblems, edgeDatabase, goalNode);
 }