OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Implicator.cc
Go to the documentation of this file.
1 /*
2  * Implicator.cc
3  *
4  * Copyright (C) 2009, 2014 Linas Vepstas
5  *
6  * Author: Linas Vepstas <linasvepstas@gmail.com> January 2009
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 
27 
28 #include "BindLinkAPI.h"
29 #include "DefaultImplicator.h"
30 #include "PatternMatch.h"
31 
32 using namespace opencog;
33 
44 bool Implicator::grounding(const std::map<Handle, Handle> &var_soln,
45  const std::map<Handle, Handle> &term_soln)
46 {
47  // PatternMatchEngine::print_solution(term_soln,var_soln);
48  Handle h = inst.instantiate(implicand, var_soln);
49  insert_result(h);
50 
51  // If we found as many as we want, then stop looking for more.
52  if (_result_set.size() < max_results)
53  return false;
54  return true;
55 }
56 
58 {
59  if (Handle::UNDEFINED != h)
60  {
61  if (_result_set.end() == _result_set.find(h))
62  {
63  _result_set.insert(h);
64  _result_changed = true;
65  }
66  }
67 }
68 
73 {
74  if (_result_changed)
75  {
76  _result_list.clear();
77  std::copy(_result_set.begin(), _result_set.end(),
78  std::back_inserter(_result_list));
79  _result_changed = false;
80  }
81  return _result_list;
82 }
83 
84 
85 namespace opencog
86 {
87 
100  const Handle& hbindlink,
101  Implicator& impl,
102  bool do_conn_check=false)
103 {
104  BindLinkPtr bl(BindLinkCast(hbindlink));
105  if (NULL == bl)
106  bl = createBindLink(*LinkCast(hbindlink));
107 
108  impl.implicand = bl->get_implicand();
109 
110  bl->imply(impl, do_conn_check);
111 
112  if (0 < impl.get_result_list().size())
113  {
114  // The result_list contains a list of the grounded expressions.
115  // (The order of the list has no significance, so it's really a set.)
116  // Put the set into a SetLink, and return that.
117  Handle gl = as->add_link(SET_LINK, impl.get_result_list());
118  return gl;
119  }
120 
121  // There are certain useful queries, where the goal of the query
122  // is to determine that some clause or set of clauses are absent
123  // from the AtomSpace. If the clauses are jointly not found, after
124  // a full and exhaustive search, then we want to run the implicator,
125  // and perform some action. Easier said than done, this code is
126  // currently a bit of a hack. It seems to work, per the AbsentUTest
127  // but is perhaps a bit fragile in its assumptions.
128  //
129  // Theoretical background: the atomspace can be thought of as a
130  // Kripke frame: it holds everything we know "right now". The
131  // AbsentLink is a check for what we don't know, right now.
132  const Pattern& pat = bl->get_pattern();
133  DefaultPatternMatchCB* intu =
134  dynamic_cast<DefaultPatternMatchCB*>(&impl);
135  if (0 == pat.mandatory.size() and 0 < pat.optionals.size()
136  and not intu->optionals_present())
137  {
138  std::map<Handle, Handle> empty_map;
139  Handle h = impl.inst.instantiate(impl.implicand, empty_map);
140  impl.insert_result(h);
141  }
142 
143  return as->add_link(SET_LINK, impl.get_result_list());
144 }
145 
156 Handle bindlink(AtomSpace* as, const Handle& hbindlink)
157 {
158  // Now perform the search.
159  DefaultImplicator impl(as);
160  return do_imply(as, hbindlink, impl);
161 }
162 
171 Handle single_bindlink (AtomSpace* as, const Handle& hbindlink)
172 {
173  // Now perform the search.
174  DefaultImplicator impl(as);
175  impl.max_results = 1;
176  return do_imply(as, hbindlink, impl);
177 }
178 
182 Handle af_bindlink(AtomSpace* as, const Handle& hbindlink)
183 {
184  // Now perform the search.
185  AFImplicator impl(as);
186  return do_imply(as, hbindlink, impl, false);
187 }
188 
189 }
190 
191 /* ===================== END OF FILE ===================== */
static Handle do_imply(AtomSpace *as, const Handle &hbindlink, Implicator &impl, bool do_conn_check=false)
Definition: Implicator.cc:99
std::vector< Handle > HandleSeq
a list of handles
Definition: Handle.h:246
static BindLinkPtr BindLinkCast(const Handle &h)
Definition: BindLink.h:62
Handle af_bindlink(AtomSpace *, const Handle &)
Definition: Implicator.cc:182
Instantiator inst
Definition: Implicator.h:65
static const Handle UNDEFINED
Definition: Handle.h:77
HandleSeq _result_list
Definition: Implicator.h:59
virtual void insert_result(const Handle &)
Definition: Implicator.cc:57
Handle instantiate(const Handle &expr, const std::map< Handle, Handle > &vars)
std::shared_ptr< BindLink > BindLinkPtr
Definition: BindLink.h:61
static LinkPtr LinkCast(const Handle &h)
Definition: Link.h:263
HandleSeq mandatory
Definition: Pattern.h:105
Handle bindlink(AtomSpace *, const Handle &)
Definition: Implicator.cc:156
virtual bool grounding(const std::map< Handle, Handle > &var_soln, const std::map< Handle, Handle > &term_soln)
Definition: Implicator.cc:44
std::set< Handle > optionals
Definition: Pattern.h:110
Handle add_link(Type t, const HandleSeq &outgoing, bool async=false)
Definition: AtomSpace.cc:175
UnorderedHandleSet _result_set
Definition: Implicator.h:58
#define createBindLink
Definition: BindLink.h:68
Handle single_bindlink(AtomSpace *, const Handle &)
Definition: Implicator.cc:171
virtual HandleSeq get_result_list()
Definition: Implicator.cc:72