/*
* opencog/atoms/grounded/GroundedSchemaNode.cc
*
* Copyright (C) 2009, 2013, 2015, 2020 Linas Vepstas
* SPDX-License-Identifier: AGPL-3.0-or-later
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License v3 as
* published by the Free Software Foundation and including the exceptions
* at http://opencog.org/wiki/Licenses
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to:
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <opencog/atoms/atom_types/atom_types.h>
#include <opencog/atomspace/AtomSpace.h>
#include "GroundedSchemaNode.h"
#include "LibraryRunner.h"
#include "PythonRunner.h"
#include "SCMRunner.h"
using namespace opencog;
GroundedSchemaNode::GroundedSchemaNode(std::string s)
: GroundedProcedureNode(GROUNDED_SCHEMA_NODE, std::move(s))
{
init();
}
GroundedSchemaNode::GroundedSchemaNode(Type t, std::string s)
: GroundedProcedureNode(t, std::move(s))
{
if (not nameserver().isA(t, GROUNDED_SCHEMA_NODE))
{
const std::string& tname = nameserver().getTypeName(t);
throw InvalidParamException(TRACE_INFO,
"Expecting a GroundedProcedureNode, got %s", tname.c_str());
}
init();
}
void GroundedSchemaNode::init()
{
_runner = nullptr;
// Get the schema name.
const std::string& schema = get_name();
// At this point, we only run scheme and python schemas.
if (0 == schema.compare(0, 4, "scm:", 4))
{
#ifdef HAVE_GUILE
// Be friendly, and strip leading white-space, if any.
size_t pos = 4;
while (' ' == schema[pos]) pos++;
_runner = new SCMRunner(schema.substr(pos));
#else
throw RuntimeException(TRACE_INFO,
"This binary does not have guile support in it; "
"Cannot evaluate scheme GroundedSchemaNode!");
#endif /* HAVE_GUILE */
return;
}
// At this point, we only run scheme, python schemas and functions from
// libraries loaded at runtime.
if (0 == schema.compare(0, 3, "py:", 3))
{
#ifdef HAVE_CYTHON
size_t pos = 3;
while (' ' == schema[pos]) pos++;
_runner = new PythonRunner(schema.substr(pos));
#else
throw RuntimeException(TRACE_INFO,
"This binary does not have python support in it; "
"Cannot evaluate python GroundedSchemaNode!");
#endif /* HAVE_CYTHON */
return;
}
if (0 == schema.compare(0, 4, "lib:", 4))
{
_runner = new LibraryRunner(schema);
return;
}
}
GroundedSchemaNode::~GroundedSchemaNode()
{
if (_runner) delete _runner;
}
/// execute_args -- execute the SchemaNode of the ExecutionOutputLink
///
/// Expects "cargs" to be a ListLink unless there is only one argument
/// Executes the GroundedSchemaNode, supplying cargs as arguments
///
ValuePtr GroundedSchemaNode::execute_args(AtomSpace* scratch,
const ValuePtr& cargs,
bool silent)
{
// Unknown procedure type
if (nullptr == _runner)
throw RuntimeException(TRACE_INFO,
"Cannot evaluate unknown Schema %s",
to_short_string().c_str());
LAZY_LOG_FINE << "Execute gsn: " << to_short_string()
<< " with arguments: " << oc_to_string(cargs)
<< std::endl;
return _runner->execute(scratch, cargs, silent);
}
DEFINE_NODE_FACTORY(GroundedSchemaNode, GROUNDED_SCHEMA_NODE)