OverviewFilesCommitsIssuesDocsReleasesPeers

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

111 lines · c ref:
/*
 * opencog/atoms/flow/GlobMatch.h
 *
 * Copyright (C) 2025 Linas Vepstas
 *
 * 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_GLOB_MATCH_H
#define _OPENCOG_GLOB_MATCH_H

#include <functional>
#include <opencog/atoms/base/Handle.h>
#include <opencog/atoms/value/Value.h>
#include <opencog/atoms/scope/Variables.h>

namespace opencog
{

/**
 * Callback types for domain-specific operations.
 *
 * GlobMatch uses these callbacks to delegate operations that require
 * domain knowledge (validation, result construction, etc.)
 */

/// Callback to validate if a pattern element matches a ground element.
/// Used for non-glob pattern elements only. Glob element validation
/// is handled internally using Variables::is_type().
///
/// @param pattern_elem  Pattern element to match
/// @param ground_elem   Ground element to match against
/// @param bindings      Accumulating variable bindings (may be updated)
/// @return true if match is valid, false otherwise
template<typename GroundSeq>
using GlobValidateCallback = std::function<
	bool(const Handle& pattern_elem,
	     const typename GroundSeq::value_type& ground_elem,
	     ValueMap& bindings)
>;

/// Callback to create a Value from a matched sequence.
/// Used to construct the glob binding value (e.g., LinkValue or List).
///
/// @param matched_seq  Sequence of ground elements matched by a glob
/// @return ValuePtr wrapping the matched sequence
template<typename GroundSeq>
using GlobMakeValueCallback = std::function<
	ValuePtr(const GroundSeq& matched_seq)
>;

/**
 * Perform glob matching with backtracking.
 *
 * Matches a pattern sequence (which may contain glob nodes) against
 * a ground sequence, using backtracking to find valid glob bindings.
 *
 * The algorithm tries to match each glob from its maximum allowed size
 * down to its minimum, backtracking when later constraints fail. This
 * ensures that all valid matchings are explored.
 *
 * @param pattern       Pattern sequence (may contain globs and variables)
 * @param ground        Ground sequence to match against
 * @param bindings      Output map of variables/globs to their bindings
 * @param variables     Variables object providing type constraints and intervals
 * @param validate      Callback to validate non-glob pattern elements
 * @param make_value    Callback to create value from matched sequence
 * @param pattern_start Index in pattern to start matching from
 * @param pattern_size  Number of pattern elements to match
 *
 * @return true if pattern matches ground with valid bindings, false otherwise
 *
 * Example usage in FilterLink:
 *   auto validate = [&](const Handle& p, const ValuePtr& g, ValueMap& b) {
 *       return this->extract(p, g, b, scratch, silent, quotation);
 *   };
 *   auto make_value = [](const ValueSeq& seq) {
 *       return createLinkValue(seq);
 *   };
 *   bool matched = glob_match(pattern, ground, bindings, _mvars,
 *                             validate, make_value, offset, size);
 */
template<typename GroundSeq>
bool glob_match(
	const HandleSeq& pattern,
	const GroundSeq& ground,
	ValueMap& bindings,
	const Variables* variables,
	GlobValidateCallback<GroundSeq> validate,
	GlobMakeValueCallback<GroundSeq> make_value,
	size_t pattern_start = 0,
	size_t pattern_size = SIZE_MAX
);

} // namespace opencog

#endif // _OPENCOG_GLOB_MATCH_H