Beispiel #1
0
        public Pebbler(Hypergraph.Hypergraph<GeometryTutorLib.ConcreteAST.GroundedClause, Hypergraph.EdgeAnnotation> graph,
                       PebblerHypergraph<ConcreteAST.GroundedClause, Hypergraph.EdgeAnnotation> pGraph)
        {
            this.graph = graph;
            this.pebblerGraph = pGraph;

            forwardPebbledEdges = new HyperEdgeMultiMap<Hypergraph.EdgeAnnotation>(pGraph.vertices.Length);
            backwardPebbledEdges = new HyperEdgeMultiMap<Hypergraph.EdgeAnnotation>(pGraph.vertices.Length);

            forwardPebbledEdges.SetOriginalHypergraph(graph);
            backwardPebbledEdges.SetOriginalHypergraph(graph);
        }
Beispiel #2
0
        //
        // The combination of new information may lead to other given information being deducible
        //
        //
        // foreach given in the problem
        //   find all edges with target given
        //   foreach edge with target with given
        //     if (all of the source nodes in edge are in the given OR path) then
        //       if this is a minimal edge (fewer sources better) then
        //         save edge
        //   if (found edge) then
        //     AddEdge to problem
        //     move target given to path
        //
        private void PerformDeducibilityCheck(HyperEdgeMultiMap <A> edgeDatabase)
        {
            // All the givens and path nodes for this problem; this includes the new edgeSources
            List <int> problemGivensAndPath = new List <int>(this.givens);

            problemGivensAndPath.AddRange(this.path);

            // foreach given in the problem

            List <int> tempGivens = new List <int>(this.givens); // Make a copy because we may be modifying it below

            foreach (int given in tempGivens)
            {
                PebblerHyperEdge <A> savedEdge = null;

                // find all edges with target given
                List <PebblerHyperEdge <A> > forwardEdges = edgeDatabase.GetBasedOnGoal(given);
                if (forwardEdges != null)
                {
                    // foreach edge with target with given
                    foreach (PebblerHyperEdge <A> edge in forwardEdges)
                    {
                        // if (all of the source nodes in edge are in the given OR path) then
                        if (Utilities.Subset <int>(problemGivensAndPath, edge.sourceNodes))
                        {
                            // if this is a minimal edge (fewer sources better) then
                            if (savedEdge == null)
                            {
                                savedEdge = edge;
                            }
                            else if (edge.sourceNodes.Count < savedEdge.sourceNodes.Count)
                            {
                                savedEdge = edge;
                            }
                        }
                    }

                    if (savedEdge != null)
                    {
                        // if (Utilities.PROBLEM_GEN_DEBUG) System.Diagnostics.Debug.WriteLine("CTA: Found another edge which can deduce givens." + savedEdge);

                        // Add the found edge to the problem
                        this.AddEdge(savedEdge);

                        // move target given to path: (1) remove from givens; (2) add to path
                        this.givens.Remove(savedEdge.targetNode);
                        Utilities.AddUnique <int>(this.path, savedEdge.targetNode);
                    }
                }
            }
        }
        //
        // Generate ALL maximal problems from the given start node (note, each incoming basic edge results in a maximal problem).
        // This gives soundness of generating problems from given nodes (current def of interesting problems), but lacks
        // completeness by not generating all of the subproblems along the way
        //
        //
        // From this node, generate all problems backward.
        // Do so by generating simple problems first (in a depth-first manner)
        //
        private List<Problem<Hypergraph.EdgeAnnotation>> GenerateAllMaximalProblemsFrom(ProblemHashMap<Hypergraph.EdgeAnnotation> memoizedProblems,
                                                                                        HyperEdgeMultiMap<Hypergraph.EdgeAnnotation> edgeDatabase, int node)
        {
            if (node == 118)
            {
                //Debug.WriteLine("NO-OP");
            }

            // 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>> edges = edgeDatabase.GetBasedOnGoal(node);

            // If there are no edges, this is a 'root' node (has no predecessors)
            if (edges == null || !edges.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 edges)
            {
                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)
            {
                GenerateMaximalProblemFromSingleEdge(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);
        }
Beispiel #4
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));
        }
Beispiel #5
0
        //
        // Given a node, pebble the reachable parts of the graph (in the forward direction)
        // We pebble in a breadth first manner
        //
        private void ForwardTraversal(HyperEdgeMultiMap<Hypergraph.EdgeAnnotation> edgeDatabase, List<int> nodesToPebble)
        {
            List<int> worklist = new List<int>(nodesToPebble);

            //
            // Pebble until the list is empty
            //
            while (worklist.Any())
            {
                // Acquire the next value to consider
                int currentNodeIndex = worklist[0];
                worklist.RemoveAt(0);

                // Pebble the current node as a forward node and percolate forward
                pebblerGraph.vertices[currentNodeIndex].pebbled = true;

                // For all hyperedges leaving this node, mark a pebble along the arc
                foreach (PebblerHyperEdge<Hypergraph.EdgeAnnotation> currentEdge in pebblerGraph.vertices[currentNodeIndex].edges)
                {
                    if (!Utilities.RESTRICTING_AXS_DEFINITIONS_THEOREMS || (Utilities.RESTRICTING_AXS_DEFINITIONS_THEOREMS && currentEdge.annotation.IsActive()))
                    {
                        if (!currentEdge.IsFullyPebbled())
                        {
                            // Indicate the node has been pebbled by adding to the list of pebbled vertices; should not have to be a unique addition
                            Utilities.AddUnique<int>(currentEdge.sourcePebbles, currentNodeIndex);

                            // With this new node, check if the edge is full pebbled; if so, percolate
                            if (currentEdge.IsFullyPebbled())
                            {
                                // Has the target of this edge been pebbled previously? Pebbled -> Pebbled means we have a backward edge
                                if (!IsNodePebbled(currentEdge.targetNode))
                                {
                                    // Success, we have an edge
                                    // Construct a static set of pebbled hyperedges for problem construction
                                    edgeDatabase.Put(currentEdge);

                                    // Add this node to the worklist to percolate further
                                    if (!worklist.Contains(currentEdge.targetNode))
                                    {
                                        worklist.Add(currentEdge.targetNode);
                                        worklist.Sort();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #6
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);
            }
        }
Beispiel #7
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);
            }
        }
Beispiel #8
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);
 }
 //
 // 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);
 }
        //
        // 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);
            }
        }
        //
        // 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);
            }
        }
Beispiel #12
0
        //
        // Create a new problem based on thisProblem and thatProblem in accordance with the above comments (repeated here)
        //
        // This problem                       { This Givens } { This Path } -> This Goal
        // The new problem is of the form:    { That Givens } { That Path } -> Goal
        //                       Combined:    { New Givens  U  This Givens \minus This Goal} {This Path  U  This Goal } -> Goal
        //
        public void Append(Hypergraph.Hypergraph <ConcreteAST.GroundedClause, Hypergraph.EdgeAnnotation> graph,
                           HyperEdgeMultiMap <A> forwardEdges, Problem <A> thatProblem)
        {
            if (thatProblem.goal == -1)
            {
                throw new ArgumentException("Attempt to append with an empty problem " + this + " " + thatProblem);
            }

            //
            // If this is an empty problem, populate it like a copy constructor and return
            //
            if (this.goal == -1)
            {
                givens = new List <int>(thatProblem.givens);
                goal   = thatProblem.goal;

                path  = new List <int>(thatProblem.path);
                edges = new List <PebblerHyperEdge <A> >(thatProblem.edges);

                suppressedGivens = new List <int>(thatProblem.suppressedGivens);

                thatProblem.edges.ForEach(edge => this.AddEdge(edge));
                return;
            }

            //
            // Standard appending of an existent problem to another existent problem
            //
            if (!this.givens.Contains(thatProblem.goal))
            {
                throw new ArgumentException("Attempt to append problems that do not connect goal->given" + this + " " + thatProblem);
            }

            // Degenerate by removing the new problem goal from THIS source node.
            this.givens.Remove(thatProblem.goal);

            // Add the 'new problem' goal node to the path of the new Problem (uniquely)
            Utilities.AddUnique <int>(this.path, thatProblem.goal);

            // Add the path nodes to THIS path
            Utilities.AddUniqueList <int>(this.path, thatProblem.path);

            // Add all the new sources to the degenerated old sources; do so uniquely
            Utilities.AddUniqueList <int>(this.givens, thatProblem.givens);
            Utilities.AddUniqueList <int>(this.suppressedGivens, thatProblem.suppressedGivens);

            // Add all of the edges of that problem to this problem; this also adds to the problem graph
            thatProblem.edges.ForEach(edge => this.AddEdge(edge));

            if (this.ContainsCycle())
            {
                throw new Exception("Problem contains a cycle" + this.graph.GetStronglyConnectedComponentDump());
                // Remove an edge from this problem?
            }

            // Now, if there exists a node in the path AND in the givens, remove it from the givens.
            foreach (int p in this.path)
            {
                if (this.givens.Remove(p))
                {
                    // if (Utilities.PROBLEM_GEN_DEBUG) System.Diagnostics.Debug.WriteLine("A node existed in the path AND givens (" + p + "); removing from givens");
                }
            }

            PerformDeducibilityCheck(forwardEdges);
        }
Beispiel #13
0
 public Pebbler(PebblerHypergraph<ConcreteAST.GroundedClause, Hypergraph.EdgeAnnotation> hypergraph)
 {
     pebblerGraph = hypergraph;
     forwardPebbledEdges = new HyperEdgeMultiMap<Hypergraph.EdgeAnnotation>(hypergraph.vertices.Length);
     backwardPebbledEdges = new HyperEdgeMultiMap<Hypergraph.EdgeAnnotation>(hypergraph.vertices.Length);
 }