OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / opencog / atoms / scope / VariableList.h

106 lines · c ref:
/*
 * opencog/atoms/scope/VariableList.h
 *
 * Copyright (C) 2015 Linas Vepstas
 * 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.
 */

#ifndef _OPENCOG_VARIABLE_LIST_H
#define _OPENCOG_VARIABLE_LIST_H

#include <opencog/util/empty_string.h>
#include <opencog/atoms/base/Handle.h>
#include <opencog/atoms/base/Link.h>
#include <opencog/atoms/scope/Variables.h>

namespace opencog
{
/** \addtogroup grp_atomspace
 *  @{
 */

/// The VariableList class records it's outgoing set in various ways
/// that make it easier and faster to work with in C++.  It implements
/// a substitute method that will replace all variables in a tree by
/// the corresponding atoms that it is given. See the .cc file for
/// more info.
///
/// The constructors make sure that the contents of the variable list
/// are syntactically correct; i.e that it actually contains variables.
/// Otherwise, it throws an error on bad syntax.  Thus, bad
/// VariableLists cannot be inserted into the atomspace.
class VariableList : public Link
{
protected:
	/// Unbundled variables and types for them.
	Variables _variables;

	VariableList(Type, const HandleSeq&);

	void throw_if_not_variable_list(Type t) const;
public:
	VariableList(const HandleSeq&& vardecls, Type=VARIABLE_LIST);
	VariableList(const Handle& hvardecls);

	VariableList(const VariableList&) = delete;
	VariableList& operator=(const VariableList&) = delete;

	// Return the list of variables we are holding.
	const Variables& get_variables(void) const { return _variables; }

	// Return true if we are holding a single variable, and the handle
	// given as the argument satisfies the type restrictions (if any).
	// Else return false.
	bool is_type(const Handle& h) const { return _variables.is_type(h); }

	// Return true if we are holding the variable `var`, and `val`
	// satisfies the type restrictions that apply to `var`.
	bool is_type(const Handle& var, const Handle& val) const
		{ return _variables.is_type(var, val); }

	// Return true if the sequence is of the same length as the variable
	// declarations we are holding, and if they satisfy all of the type
	// restrictions (if any).
	bool is_type(const HandleSeq& hseq) const { return _variables.is_type(hseq); }

	// Given the tree `tree` containing variables in it, create and
	// return a new tree with the indicated arguments `args` substituted
	// for the variables. The `args` must pass the typecheck, else an
	// exception is thrown.
	Handle substitute(const Handle& tree, const HandleSeq& args) const
		{ return _variables.substitute(tree, args); }

	static Handle factory(const Handle&);
};

LINK_PTR_DECL(VariableList)
#define createVariableList CREATE_DECL(VariableList)

// Debugging helpers see
// http://wiki.opencog.org/w/Development_standards#Print_OpenCog_Objects
// The reason indent is not an optional argument with default is
// because gdb doesn't support that, see
// http://stackoverflow.com/questions/16734783 for more explanation.
std::string oc_to_string(const VariableListPtr& vlp,
                         const std::string& indent=empty_string);

/** @}*/
}

#endif // _OPENCOG_VARIABLE_LIST_H