OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
EvaluationLink.cc
Go to the documentation of this file.
1 /*
2  * opencog/atoms/execution/EvaluationLink.cc
3  *
4  * Copyright (C) 2009, 2013, 2014, 2015 Linas Vepstas
5  * All Rights Reserved
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License v3 as
9  * published by the Free Software Foundation and including the exceptions
10  * at http://opencog.org/wiki/Licenses
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program; if not, write to:
19  * Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #include <opencog/atomspace/atom_types.h>
30 #include "EvaluationLink.h"
31 
32 using namespace opencog;
33 
37  : FreeLink(EVALUATION_LINK, oset, tv, av)
38 {
39  if ((2 != oset.size()) or
40  (LIST_LINK != oset[1]->getType()))
41  {
42  throw RuntimeException(TRACE_INFO,
43  "EvaluationLink must have predicate and args!");
44  }
45 }
46 
50  : FreeLink(EVALUATION_LINK, schema, args, tv, av)
51 {
52  if (LIST_LINK != args->getType()) {
53  throw RuntimeException(TRACE_INFO,
54  "EvaluationLink must have args in a ListLink!");
55  }
56 }
57 
59  : FreeLink(l)
60 {
61  Type tscope = l.getType();
62  if (EVALUATION_LINK != tscope) {
63  throw RuntimeException(TRACE_INFO,
64  "Expecting an EvaluationLink");
65  }
66 }
67 
68 // Perform a GreaterThan check
70 {
71  if (2 != ll->getArity())
72  throw RuntimeException(TRACE_INFO,
73  "GreaterThankLink expects two arguments");
74  Handle h1(ll->getOutgoingAtom(0));
75  Handle h2(ll->getOutgoingAtom(1));
76 
77  // If they are not numbers, then we expect them to be something that
78  // can be executed, yeilding a number.
79  if (NUMBER_NODE != h1->getType())
80  h1 = FunctionLink::do_execute(as, h1);
81 
82  if (NUMBER_NODE != h2->getType())
83  h2 = FunctionLink::do_execute(as, h2);
84 
87 
88  if (NULL == n1 or NULL == n2)
89  throw RuntimeException(TRACE_INFO,
90  "Expecting c++:greater arguments to be NumberNode's! Got:\n%s\n",
91  (h1==NULL)? "(invalid handle)" : h1->toShortString().c_str(),
92  (h2==NULL)? "(invalid handle)" : h2->toShortString().c_str());
93 
94  if (n1->get_value() > n2->get_value())
95  return TruthValue::TRUE_TV();
96  else
97  return TruthValue::FALSE_TV();
98 }
99 
101 {
102  const HandleSeq& oset = ll->getOutgoingSet();
103  if (2 != oset.size())
104  throw RuntimeException(TRACE_INFO,
105  "EqualLink expects two arguments");
106  if (oset[0] == oset[1])
107  return TruthValue::TRUE_TV();
108  else
109  return TruthValue::FALSE_TV();
110 }
111 
128 {
129  Type t = execlnk->getType();
130  if (EVALUATION_LINK == t)
131  {
132  LinkPtr l(LinkCast(execlnk));
133  return do_evaluate(as, l->getOutgoingSet());
134  }
135  else if (EQUAL_LINK == t)
136  {
137  return equal(as, LinkCast(execlnk));
138  }
139  else if (GREATER_THAN_LINK == t)
140  {
141  return greater(as, LinkCast(execlnk));
142  }
143  else if (NOT_LINK == t)
144  {
145  LinkPtr l(LinkCast(execlnk));
146  TruthValuePtr tv(do_evaluate(as, l->getOutgoingAtom(0)));
148  1.0 - tv->getMean(), tv->getCount());
149  }
150  throw RuntimeException(TRACE_INFO, "Expecting to get an EvaluationLink!");
151 }
152 
161 {
162  if (2 != sna.size())
163  {
164  throw RuntimeException(TRACE_INFO,
165  "Incorrect arity for an EvaluationLink!");
166  }
167  return do_evaluate(as, sna[0], sna[1]);
168 }
169 
177 {
178  if (GROUNDED_PREDICATE_NODE != gsn->getType())
179  {
180  throw RuntimeException(TRACE_INFO, "Expecting GroundedPredicateNode!");
181  }
182  if (LIST_LINK != args->getType())
183  {
184  throw RuntimeException(TRACE_INFO, "Expecting arguments to EvaluationLink!");
185  }
186 
187  // Get the schema name.
188  const std::string& schema = NodeCast(gsn)->getName();
189  // printf ("Grounded schema name: %s\n", schema.c_str());
190 
191  // A very special-case C++ comparison.
192  // This compares two NumberNodes, by their numeric value.
193  // Hard-coded in C++ for speed. (well, and for convenience ...)
194  if (0 == schema.compare("c++:greater"))
195  {
196  return greater(as, LinkCast(args));
197  }
198 
199  // A very special-case C++ comparison.
200  // This compares a set of atoms, verifying that they are all different.
201  // Hard-coded in C++ for speed. (well, and for convenience ...)
202  if (0 == schema.compare("c++:exclusive"))
203  {
204  LinkPtr ll(LinkCast(args));
205  Arity sz = ll->getArity();
206  for (Arity i=0; i<sz-1; i++) {
207  Handle h1(ll->getOutgoingAtom(i));
208  for (Arity j=i+1; j<sz; j++) {
209  Handle h2(ll->getOutgoingAtom(j));
210  if (h1 == h2) return TruthValue::FALSE_TV();
211  }
212  }
213  return TruthValue::TRUE_TV();
214  }
215 
216  // At this point, we only run scheme and python schemas.
217  if (0 == schema.compare(0,4,"scm:", 4))
218  {
219 #ifdef HAVE_GUILE
220  // Be friendly, and strip leading white-space, if any.
221  size_t pos = 4;
222  while (' ' == schema[pos]) pos++;
223 
224  SchemeEval* applier = SchemeEval::get_evaluator(as);
225  return applier->apply_tv(schema.substr(pos), args);
226 #else
227  throw RuntimeException(TRACE_INFO,
228  "Cannot evaluate scheme GroundedPredicateNode!");
229 #endif /* HAVE_GUILE */
230  }
231 
232  if (0 == schema.compare(0, 3,"py:", 3))
233  {
234 #ifdef HAVE_CYTHON
235  // Be friendly, and strip leading white-space, if any.
236  size_t pos = 3;
237  while (' ' == schema[pos]) pos++;
238 
239  // Be sure to specify the atomspace in which to work!
240  PythonEval &applier = PythonEval::instance();
241  return applier.apply_tv(as, schema.substr(pos), args);
242 #else
243  throw RuntimeException(TRACE_INFO,
244  "Cannot evaluate python GroundedPredicateNode!");
245 #endif /* HAVE_CYTHON */
246  }
247 
248  // Unkown proceedure type.
249  throw RuntimeException(TRACE_INFO,
250  "Cannot evaluate unknown GroundedPredicateNode: %s",
251  schema.c_str());
252 }
std::vector< Handle > HandleSeq
a list of handles
Definition: Handle.h:246
static TruthValuePtr TRUE_TV()
Definition: TruthValue.cc:59
std::shared_ptr< TruthValue > TruthValuePtr
Definition: TruthValue.h:85
std::shared_ptr< AttentionValue > AttentionValuePtr
Type getType() const
Definition: Atom.h:197
std::shared_ptr< Link > LinkPtr
Definition: Atom.h:53
static NodePtr NodeCast(const Handle &h)
Definition: Node.h:113
std::shared_ptr< NumberNode > NumberNodePtr
Definition: NumberNode.h:76
static PythonEval & instance(AtomSpace *atomspace=NULL)
Definition: PythonEval.cc:416
static SchemeEval * get_evaluator(AtomSpace *=NULL)
Definition: SchemeEval.cc:1135
tuple args
Definition: benchmark.py:79
static TruthValuePtr createTV(strength_t mean, count_t count)
static TruthValuePtr FALSE_TV()
Definition: TruthValue.cc:66
static LinkPtr LinkCast(const Handle &h)
Definition: Link.h:263
static NumberNodePtr NumberNodeCast(const Handle &h)
Definition: NumberNode.h:77
TruthValuePtr apply_tv(const std::string &func, Handle varargs)
Definition: SchemeEval.cc:1053
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40
TruthValuePtr apply_tv(AtomSpace *, const std::string &func, Handle varargs)
Definition: PythonEval.cc:851
unsigned short Arity
arity of Links, represented as short integer (16 bits)
Definition: Link.h:40