OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ExecutionOutputLink.cc
Go to the documentation of this file.
1 /*
2  * opencog/atoms/execution/ExecutionOutputLink.cc
3  *
4  * Copyright (C) 2009, 2013, 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 <stdlib.h>
24 
25 #include <opencog/atomspace/atom_types.h>
33 
34 #include "ExecutionOutputLink.h"
35 #include "Instantiator.h"
36 
37 using namespace opencog;
38 
42  : FunctionLink(EXECUTION_OUTPUT_LINK, oset, tv, av)
43 {
44  if (2 != oset.size() or
45  GROUNDED_SCHEMA_NODE != oset[0]->getType() or
46  LIST_LINK != oset[1]->getType())
47  {
48  throw RuntimeException(TRACE_INFO,
49  "ExecutionOutputLink must have schema and args!");
50  }
51 }
52 
54  const Handle& args,
57  : FunctionLink(EXECUTION_OUTPUT_LINK, schema, args, tv, av)
58 {
59  if (GROUNDED_SCHEMA_NODE != schema->getType())
60  throw RuntimeException(TRACE_INFO, "Expecting GroundedSchemaNode!");
61 
62  if (LIST_LINK != args->getType())
63  throw RuntimeException(TRACE_INFO,
64  "ExecutionOutputLink must have schema and args!");
65 }
66 
68  : FunctionLink(l)
69 {
70  Type tscope = l.getType();
71  if (EXECUTION_OUTPUT_LINK != tscope)
72  throw RuntimeException(TRACE_INFO,
73  "Expection an ExecutionOutputLink!");
74 }
75 
91 {
92  return do_execute(as, _outgoing[0], _outgoing[1]);
93 }
94 
102  const Handle& gsn, const Handle& cargs)
103 {
104  // Search for additional execution links, and execute them too.
105  // We will know that happend if the returned handle differs from
106  // the input handle. If the results are different, add the new
107  // results to the atomspace. We need to do this, because scheme,
108  // and python expects to find thier arguments in the atomspace,
109  // but this is arguably broken, as it pollutes the atomspace with
110  // junk that is never cleaned up. We punt for now, but something
111  // should be done about this. XXX FIXME ...
112  Instantiator inst(as);
113  LinkPtr largs(LinkCast(cargs));
114  Handle args(cargs);
115  if (largs)
116  {
117  std::vector<Handle> new_oset;
118  bool changed = false;
119  for (Handle ho : largs->getOutgoingSet())
120  {
121  Handle nh(inst.execute(ho));
122  // nh might be NULL if ho was a DeleteLink
123  if (nh != NULL)
124  new_oset.push_back(nh);
125  if (nh != ho) changed = true;
126  }
127  if (changed)
128  args = as->add_link(LIST_LINK, new_oset);
129  }
130 
131  // Get the schema name.
132  const std::string& schema = NodeCast(gsn)->getName();
133  // printf ("Grounded schema name: %s\n", schema.c_str());
134 
135  // At this point, we only run scheme and python schemas.
136  if (0 == schema.compare(0,4,"scm:", 4))
137  {
138 #ifdef HAVE_GUILE
139  // Be friendly, and strip leading white-space, if any.
140  size_t pos = 4;
141  while (' ' == schema[pos]) pos++;
142 
143  SchemeEval* applier = SchemeEval::get_evaluator(as);
144  Handle h(applier->apply(schema.substr(pos), args));
145 
146  // Exceptions were already caught, before leaving guile mode,
147  // so we can't rethrow. Just throw a new exception.
148  if (applier->eval_error())
149  throw RuntimeException(TRACE_INFO,
150  "Failed evaluation; see logfile for stack trace.");
151  return h;
152 #else
153  throw RuntimeException(TRACE_INFO,
154  "Cannot evaluate scheme GroundedSchemaNode!");
155 #endif /* HAVE_GUILE */
156  }
157 
158  if (0 == schema.compare(0, 3,"py:", 3))
159  {
160 #ifdef HAVE_CYTHON
161  // Be friendly, and strip leading white-space, if any.
162  size_t pos = 3;
163  while (' ' == schema[pos]) pos++;
164 
165  // Get a reference to the python evaluator.
166  // Be sure to specify the atomspace in which the
167  // evaluation is to be performed.
168  PythonEval &applier = PythonEval::instance();
169  Handle h = applier.apply(as, schema.substr(pos), args);
170 
171  // Return the handle
172  return h;
173 #else
174  throw RuntimeException(TRACE_INFO,
175  "Cannot evaluate python GroundedSchemaNode!");
176 #endif /* HAVE_CYTHON */
177  }
178 
179  // Unkown proceedure type.
180  throw RuntimeException(TRACE_INFO,
181  "Cannot evaluate unknown GroundedSchemaNode!");
182 }
Handle apply(const std::string &func, Handle varargs)
Definition: SchemeEval.cc:963
std::vector< Handle > HandleSeq
a list of handles
Definition: Handle.h:246
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
static PythonEval & instance(AtomSpace *atomspace=NULL)
Definition: PythonEval.cc:416
virtual bool eval_error(void)
Definition: GenericEval.h:75
static SchemeEval * get_evaluator(AtomSpace *=NULL)
Definition: SchemeEval.cc:1135
Handle apply(AtomSpace *, const std::string &func, Handle varargs)
Definition: PythonEval.cc:799
tuple args
Definition: benchmark.py:79
static LinkPtr LinkCast(const Handle &h)
Definition: Link.h:263
Handle execute(const Handle &expr)
Definition: Instantiator.h:70
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40
Handle add_link(Type t, const HandleSeq &outgoing, bool async=false)
Definition: AtomSpace.cc:175