OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PatternMatchEngine.h
Go to the documentation of this file.
1 /*
2  * PatternMatchEngine.h
3  *
4  * Author: Linas Vepstas February 2008
5  *
6  * Copyright (C) 2008,2009 Linas Vepstas <linasvepstas@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Affero General Public License v3 as
10  * published by the Free Software Foundation and including the exceptions
11  * at http://opencog.org/wiki/Licenses
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Affero General Public License
19  * along with this program; if not, write to:
20  * Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifndef _OPENCOG_PATTERN_MATCH_ENGINE_H
25 #define _OPENCOG_PATTERN_MATCH_ENGINE_H
26 
27 #include <map>
28 #include <set>
29 #include <stack>
30 #include <unordered_map>
31 #include <vector>
32 
33 #include <opencog/query/Pattern.h>
36 
37 namespace opencog {
38 
40 {
41  // -------------------------------------------
42  // Callback to whom the results are reported.
45 
46  // Private, locally scoped typedefs, not used outside of this class.
47 
48  private:
49  // -------------------------------------------
50  // The current set of clauses (redex context) being grounded.
51  // A single redex consists of a collection of clauses, all of
52  // which must be grounded.
53  bool explore_redex(const Handle&, const Handle&, const Handle&);
54 
55  // These have to be pointers, not references; they get pushed
56  // onto a stack when a new redex context is started. This is
57  // how redex recursion will (eventually) be implemented.
59  const Pattern* _pat;
60 
61  bool is_optional(const Handle& h) {
62  return (_pat->optionals.count(h) != 0); }
63 
64  bool is_evaluatable(const Handle& h) {
65  return (_pat->evaluatable_holders.count(h) != 0); }
66 
67  bool is_black(const Handle& h) {
68  return (_pat->black.count(h) != 0); }
69 
70  // -------------------------------------------
71  // Recursive redex support. These are stacks of the clauses
72  // above, that are being searched.
73  std::stack<const Variables*> _stack_variables;
74  std::stack<const Pattern*> _stack_pattern;
75 
76  void push_redex(void);
77  void pop_redex(void);
78 
79  // --------------------------------------------
80  // Current clause traversal state. These hold the state needed
81  // to traverse a single clause, and find groundings for it.
82  // Note, though, that these are cumulative: so e.g. the
83  // var_grounding map accumulates variable groundings for this
84  // clause, and all previous clauses so far.
85 
86  // Map of current groundings of variables to thier grounds
87  // Also contains grounds of subclauses (not sure why, this seems
88  // to be needed)
89  std::map<Handle, Handle> var_grounding;
90  // Map of clauses to their current groundings
91  std::map<Handle, Handle> clause_grounding;
92 
93  void clear_current_state(void); // clear the stuff above
94 
95  // -------------------------------------------
96  // ChoiceLink state management
97  typedef std::pair<PatternTermPtr, Handle> Choice;
98  typedef std::map<Choice, size_t> ChoiceState;
99 
102 
103  size_t curr_choice(const PatternTermPtr&, const Handle&, bool&);
104  bool have_choice(const PatternTermPtr&, const Handle&);
105 
106  // Iteration control for choice links. Branchpoint advances
107  // whenever take_step is set to true.
109 
110  // -------------------------------------------
111  // Unordered Link suppoprt
112  typedef std::pair<PatternTermPtr, Handle> Unorder; // Choice
114  typedef std::map<Unorder, Permutation> PermState; // ChoiceState
115 
117  Permutation curr_perm(const PatternTermPtr&, const Handle&, bool&);
118  bool have_perm(const PatternTermPtr&, const Handle&);
119 
120  // Iteration control for unordered links. Branchpoint advances
121  // whenever take_step is set to true.
122  bool take_step;
123  bool have_more;
124 #ifdef DEBUG
125  std::map<Unorder, int> perm_count;
126  std::stack<std::map<Unorder, int>> perm_count_stack;
127 #endif
128 
129  // --------------------------------------------
130  // Methods and state that select the next clause to be grounded.
131 
132  bool do_next_clause(void);
134  void get_next_untried_clause(void);
135  bool get_next_thinnest_clause(bool, bool, bool);
136  unsigned int thickness(const Handle&, const std::set<Handle>&);
139  // Set of clauses for which a grounding is currently being attempted.
140  typedef std::set<Handle> IssuedSet;
141  IssuedSet issued; // stacked on issued_stack
142 
143  // -------------------------------------------
144  // Stack used to store current traversal state for a single
145  // clause. These are pushed when a clause is fully grounded,
146  // and a new clause is about to be started. These are popped
147  // in order to get back to the original clause, and resume
148  // traversal of that clause, where it was last left off.
149  void solution_push(void);
150  void solution_pop(void);
151  void solution_drop(void);
152 
153  // Stacks containing partial groundings.
154  typedef std::map<Handle, Handle> SolnMap;
155  std::stack<SolnMap> var_solutn_stack;
156  std::stack<SolnMap> term_solutn_stack;
157 
158  std::stack<IssuedSet> issued_stack;
159  std::stack<ChoiceState> choice_stack;
160 
161  std::stack<PermState> perm_stack;
162  void perm_push(void);
163  void perm_pop(void);
164 
165  // push, pop and clear these states.
166  void clause_stacks_push(void);
167  void clause_stacks_pop(void);
168  void clause_stacks_clear(void);
169  unsigned int _clause_stack_depth;
170 
171  // -------------------------------------------
172  // Recursive tree comparison algorithm.
173  unsigned int depth; // Recursion depth for tree_compare.
174  bool in_quote; // Everything below a quote is literal.
175 
176  typedef enum {
183  } Caller; // temporary scaffolding !???
184 
185  bool tree_compare(const PatternTermPtr&, const Handle&, Caller);
186 
187  bool quote_compare(const PatternTermPtr&, const Handle&);
188  bool variable_compare(const Handle&, const Handle&);
189  bool self_compare(const Handle&);
190  bool node_compare(const Handle&, const Handle&);
191  bool redex_compare(const LinkPtr&, const LinkPtr&);
192  bool choice_compare(const PatternTermPtr&, const Handle&,
193  const LinkPtr&, const LinkPtr&);
194  bool ordered_compare(const PatternTermPtr&, const Handle&,
195  const LinkPtr&, const LinkPtr&);
196  bool unorder_compare(const PatternTermPtr&, const Handle&,
197  const LinkPtr&, const LinkPtr&);
198 
199  // -------------------------------------------
200  // Upwards-walking and grounding of a single clause.
201  // See PatternMatchEngine.cc for descriptions
202  bool explore_clause(const Handle&, const Handle&, const Handle&);
203  bool explore_term_branches(const Handle&, const Handle&,
204  const Handle&);
205  bool explore_up_branches(const PatternTermPtr&, const Handle&,
206  const Handle&);
207  bool explore_link_branches(const PatternTermPtr&, const Handle&,
208  const Handle&);
209  bool explore_choice_branches(const PatternTermPtr&, const Handle&,
210  const Handle&);
211  bool explore_single_branch(const PatternTermPtr&, const Handle&,
212  const Handle&);
213  bool do_term_up(const PatternTermPtr&, const Handle&,
214  const Handle&);
215  bool clause_accept(const Handle&, const Handle&);
216 
217  public:
219  const Variables&,
220  const Pattern&);
221 
222  // Examine the locally connected neighborhood for possible
223  // matches.
224  bool explore_neighborhood(const Handle&, const Handle&, const Handle&);
225 
226  // Handy-dandy utilities
227  static void print_solution(const std::map<Handle, Handle> &vars,
228  const std::map<Handle, Handle> &clauses);
229 
230  static void print_term(const std::set<Handle> &vars,
231  const std::vector<Handle> &clauses);
232 };
233 
234 } // namespace opencog
235 
236 #endif // _OPENCOG_PATTERN_MATCH_ENGINE_H
bool explore_neighborhood(const Handle &, const Handle &, const Handle &)
std::stack< SolnMap > var_solutn_stack
PatternMatchEngine(PatternMatchCallback &, const Variables &, const Pattern &)
std::shared_ptr< PatternTerm > PatternTermPtr
Definition: PatternTerm.h:35
std::set< Handle > evaluatable_holders
Definition: Pattern.h:121
static void print_solution(const std::map< Handle, Handle > &vars, const std::map< Handle, Handle > &clauses)
std::stack< const Pattern * > _stack_pattern
bool do_term_up(const PatternTermPtr &, const Handle &, const Handle &)
std::map< Handle, Handle > var_grounding
std::map< Handle, Handle > clause_grounding
bool have_choice(const PatternTermPtr &, const Handle &)
std::shared_ptr< Link > LinkPtr
Definition: Atom.h:53
std::pair< PatternTermPtr, Handle > Choice
std::vector< PatternTermPtr > PatternTermSeq
Definition: PatternTerm.h:37
bool get_next_thinnest_clause(bool, bool, bool)
bool self_compare(const Handle &)
bool explore_link_branches(const PatternTermPtr &, const Handle &, const Handle &)
std::stack< SolnMap > term_solutn_stack
bool explore_choice_branches(const PatternTermPtr &, const Handle &, const Handle &)
bool quote_compare(const PatternTermPtr &, const Handle &)
std::map< Choice, size_t > ChoiceState
unsigned int thickness(const Handle &, const std::set< Handle > &)
bool is_black(const Handle &h)
std::pair< PatternTermPtr, Handle > Unorder
PatternMatchCallback & _pmc
bool explore_single_branch(const PatternTermPtr &, const Handle &, const Handle &)
bool variable_compare(const Handle &, const Handle &)
bool explore_redex(const Handle &, const Handle &, const Handle &)
std::stack< const Variables * > _stack_variables
std::stack< IssuedSet > issued_stack
bool unorder_compare(const PatternTermPtr &, const Handle &, const LinkPtr &, const LinkPtr &)
bool is_optional(const Handle &h)
std::set< Handle > black
Definition: Pattern.h:116
std::stack< ChoiceState > choice_stack
bool redex_compare(const LinkPtr &, const LinkPtr &)
Definition: Composition.cc:90
static void print_term(const std::set< Handle > &vars, const std::vector< Handle > &clauses)
std::set< Handle > optionals
Definition: Pattern.h:110
std::map< Handle, Handle > SolnMap
bool explore_clause(const Handle &, const Handle &, const Handle &)
std::map< Unorder, Permutation > PermState
bool ordered_compare(const PatternTermPtr &, const Handle &, const LinkPtr &, const LinkPtr &)
size_t curr_choice(const PatternTermPtr &, const Handle &, bool &)
bool explore_term_branches(const Handle &, const Handle &, const Handle &)
bool clause_accept(const Handle &, const Handle &)
Permutation curr_perm(const PatternTermPtr &, const Handle &, bool &)
bool explore_up_branches(const PatternTermPtr &, const Handle &, const Handle &)
bool is_evaluatable(const Handle &h)
bool tree_compare(const PatternTermPtr &, const Handle &, Caller)
bool choice_compare(const PatternTermPtr &, const Handle &, const LinkPtr &, const LinkPtr &)
bool have_perm(const PatternTermPtr &, const Handle &)
bool node_compare(const Handle &, const Handle &)
Compare two nodes, one in the pattern, one proposed grounding.
std::stack< PermState > perm_stack