<commit_before>/*
 * PatternMatchEngine.h
 *
 * Author: <NAME> February 2008
 *
 * Copyright (C) 2008,2009 <NAME> <<EMAIL>>
 *
 * 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_PATTERN_MATCH_ENGINE_H
#define _OPENCOG_PATTERN_MATCH_ENGINE_H

#include <map>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

#include <opencog/query/Pattern.h>
#include <opencog/query/PatternMatchCallback.h>
#include <opencog/atomspace/ClassServer.h>

namespace opencog {

class PatternMatchEngine
{
	// -------------------------------------------
	// Callback to whom the results are reported.
	PatternMatchCallback &_pmc;
	ClassServer& _classserver;

	// Private, locally scoped typedefs, not used outside of this class.

	private:
		// -------------------------------------------
		// The current set of clauses (redex context) being grounded.
		// A single redex consists of a collection of clauses, all of
		// which must be grounded.
		bool explore_redex(const Handle&, const Handle&, const Handle&);

		// These have to be pointers, not references; they get pushed
		// onto a stack when a new redex context is started. This is
		// how redex recursion will (eventually) be implemented.
		const Variables* _varlist;
		const Pattern* _pat;

		bool is_optional(const Handle& h) {
			return (_pat->optionals.count(h) != 0); }

		bool is_evaluatable(const Handle& h) {
			return (_pat->evaluatable_holders.count(h) != 0); }

		bool is_black(const Handle& h) {
			return (_pat->black.count(h) != 0); }

		// -------------------------------------------
		// Recursive redex support. These are stacks of the clauses
		// above, that are being searched.
		std::stack<const Variables*>  _stack_variables;
		std::stack<const Pattern*>    _stack_pattern;

		void push_redex(void);
		void pop_redex(void);

		// --------------------------------------------
		// Current clause traversal state. These hold the state needed
		// to traverse a single clause, and find groundings for it.
		// Note, though, that these are cumulative: so e.g. the
		// var_grounding map accumulates variable groundings for this
		// clause, and all previous clauses so far.

		// Map of current groundings of variables to thier grounds
		// Also contains grounds of subclauses (not sure why, this seems
		// to be needed)
		std::map<Handle, Handle> var_grounding;
		// Map of clauses to their current groundings
		std::map<Handle, Handle> clause_grounding;

		// Set of clauses for which a grounding is currently being attempted.
		typedef std::set<Handle> IssuedSet;
		IssuedSet issued;     // stacked on issued_stack

		unsigned int depth; // Recursion depth for tree_compare.
		bool in_quote;      // Everything is literal in a quote.

		Handle curr_root;         // stacked onto root_handle_stack
		Handle curr_soln_handle;  // stacked onto soln_handle_stack
		Handle curr_term_handle;  // stacked onto term_handle_stack

		void clear_current_state(void);  // clear the stuff above

		// -------------------------------------------
		// OrLink (choice) state management
		typedef std::pair<const Handle&, const Handle&> Choice;
		typedef std::map<Choice, size_t> ChoiceState;

		ChoiceState _choice_state;
		bool _need_choice_push;

		size_t next_choice(const Handle&, const Handle&);

		// -------------------------------------------
		// New Unordered Link suppoprt
		typedef std::vector<Handle> Permutation;
		typedef std::pair<const Handle&, const Handle&> Unorder; // Choice
		typedef std::map<Unorder, Permutation> PermState; // ChoiceState

		PermState _perm_state;
		bool _need_perm_push;  // XXX ???
		Permutation next_perm(const Handle&, const Handle&);
		bool have_perm(const Handle&, const Handle&);

		bool have_more;
		typedef std::stack<bool> MoreStack;
		MoreStack more_stack;

		// -------------------------------------------
		// Stack used to store current traversal state for a single
		// clause. These are pushed when a clause is fully grounded,
		// and a new clause is about to be started. These are popped
		// in order to get back to the original clause, and resume
		// traversal of that clause, where it was last left off.
		std::stack<Handle> root_handle_stack;
		std::stack<Handle> term_handle_stack;
		std::stack<Handle> soln_handle_stack;
		void solution_push(void);
		void solution_pop(void);<commit_msg>Fix for very  serious, very difficult bug.<commit_after>/*
 * PatternMatchEngine.h
 *
 * Author: <NAME> February 2008
 *
 * Copyright (C) 2008,2009 <NAME> <<EMAIL>>
 *
 * 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_PATTERN_MATCH_ENGINE_H
#define _OPENCOG_PATTERN_MATCH_ENGINE_H

#include <map>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

#include <opencog/query/Pattern.h>
#include <opencog/query/PatternMatchCallback.h>
#include <opencog/atomspace/ClassServer.h>

namespace opencog {

class PatternMatchEngine
{
	// -------------------------------------------
	// Callback to whom the results are reported.
	PatternMatchCallback &_pmc;
	ClassServer& _classserver;

	// Private, locally scoped typedefs, not used outside of this class.

	private:
		// -------------------------------------------
		// The current set of clauses (redex context) being grounded.
		// A single redex consists of a collection of clauses, all of
		// which must be grounded.
		bool explore_redex(const Handle&, const Handle&, const Handle&);

		// These have to be pointers, not references; they get pushed
		// onto a stack when a new redex context is started. This is
		// how redex recursion will (eventually) be implemented.
		const Variables* _varlist;
		const Pattern* _pat;

		bool is_optional(const Handle& h) {
			return (_pat->optionals.count(h) != 0); }

		bool is_evaluatable(const Handle& h) {
			return (_pat->evaluatable_holders.count(h) != 0); }

		bool is_black(const Handle& h) {
			return (_pat->black.count(h) != 0); }

		// -------------------------------------------
		// Recursive redex support. These are stacks of the clauses
		// above, that are being searched.
		std::stack<const Variables*>  _stack_variables;
		std::stack<const Pattern*>    _stack_pattern;

		void push_redex(void);
		void pop_redex(void);

		// --------------------------------------------
		// Current clause traversal state. These hold the state needed
		// to traverse a single clause, and find groundings for it.
		// Note, though, that these are cumulative: so e.g. the
		// var_grounding map accumulates variable groundings for this
		// clause, and all previous clauses so far.

		// Map of current groundings of variables to thier grounds
		// Also contains grounds of subclauses (not sure why, this seems
		// to be needed)
		std::map<Handle, Handle> var_grounding;
		// Map of clauses to their current groundings
		std::map<Handle, Handle> clause_grounding;

		// Set of clauses for which a grounding is currently being attempted.
		typedef std::set<Handle> IssuedSet;
		IssuedSet issued;     // stacked on issued_stack

		unsigned int depth; // Recursion depth for tree_compare.
		bool in_quote;      // Everything is literal in a quote.

		Handle curr_root;         // stacked onto root_handle_stack
		Handle curr_soln_handle;  // stacked onto soln_handle_stack
		Handle curr_term_handle;  // stacked onto term_handle_stack

		void clear_current_state(void);  // clear the stuff above

		// -------------------------------------------
		// OrLink (choice) state management
		typedef std::pair<Handle, Handle> Choice;
		typedef std::map<Choice, size_t> ChoiceState;

		ChoiceState _choice_state;
		bool _need_choice_push;

		size_t next_choice(const Handle&, const Handle&);

		// -------------------------------------------
		// New Unordered Link suppoprt
		typedef std::vector<Handle> Permutation;
		typedef std::pair<Handle, Handle> Unorder; // Choice
		typedef std::map<Unorder, Permutation> PermState; // ChoiceState

		PermState _perm_state;
		bool _need_perm_push;  // XXX ???
		Permutation next_perm(const Handle&, const Handle&);
		bool have_perm(const Handle&, const Handle&);

		bool have_more;
		typedef std::stack<bool> MoreStack;
		MoreStack more_stack;

		// -------------------------------------------
		// Stack used to store current traversal state for a single
		// clause. These are pushed when a clause is fully grounded,
		// and a new clause is about to be started. These are popped
		// in order to get back to the original clause, and resume
		// traversal of that clause, where it was last left off.
		std::stack<Handle> root_handle_stack;
		std::stack<Handle> term_handle_stack;
		std::stack<Handle> soln_handle_stack;
		void solution_push(void);
		void solution_pop(void);
{'fraction_non_alphanumeric': 0.144038250821795, 'fraction_numerical': 0.005379021814921805, 'mean_word_length': 2.8960031043849437, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '954055', 'n_tokens_mistral': 3095, 'n_tokens_neox': 2774, 'n_words': 1071}