OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-ure / opencog / ure / forwardchainer / SourceRuleSet.cc

140 lines · cc ref:
/*
 * SourceRuleSet.cc
 *
 * Copyright (C) 2020 SingularityNET Foundation
 * Author: Nil Geisweiller
 *
 * 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 "SourceRuleSet.h"

#include <boost/range/algorithm/lower_bound.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>

#include <opencog/util/oc_assert.h>

namespace opencog {

SourceRule::SourceRule(SourcePtr src, RulePtr rl)
	: source(src), rule(rl)
{
}

SourceRule::~SourceRule()
{
}

bool SourceRule::operator==(const SourceRule& other) const
{
	return &source == &other.source and &rule == &other.rule;
}

bool SourceRule::operator<(const SourceRule& other) const
{
	return (&source < &other.source)
		or (&source == &other.source and &rule < &other.rule);
}

bool SourceRule::is_valid() const
{
	return source != nullptr and rule != nullptr;
}

std::string SourceRule::to_string(const std::string& indent) const
{
	static const std::string nullstr("nullptr");
	std::stringstream ss;
	// Only print hash because not the master container
	ss << indent << "source[" << source << "]: "
	   << (source ? source->body->id_to_string() : nullstr)
	   << std::endl << indent << "rule[" << rule << "]: "
	   << (rule ? rule->to_short_string() : nullstr);
	return ss.str();
}

SourceRuleSet::SourceRuleSet()
	: _thompson_smp(tv_seq)
{
}

bool SourceRuleSet::insert(const SourceRule& sr, TruthValuePtr tv)
{
	auto it = boost::lower_bound(source_rule_seq, sr);
	if (it == source_rule_seq.end() or *it != sr) {
		it = source_rule_seq.insert(it, sr);
		size_t idx = std::distance(source_rule_seq.begin(), it);
		tv_seq.insert(std::next(tv_seq.begin(), idx), tv);
		return true;
	}
	// The pair is already in the source rule set
	return false;
}

std::pair<SourceRule, TruthValuePtr> SourceRuleSet::thompson_select()
{
	if (tv_seq.empty())
		return {SourceRule(), nullptr};

	// Select the next source rule pair to apply
	size_t rnd_idx = _thompson_smp();
	SourceRule slc_sr = source_rule_seq[rnd_idx];
	TruthValuePtr slc_tv = tv_seq[rnd_idx];

	// Remove it from the container to not be selected again
	source_rule_seq.erase(std::next(source_rule_seq.begin(), rnd_idx));
	tv_seq.erase(std::next(tv_seq.begin(), rnd_idx));

	// Return the selected source rule pair
	return {slc_sr, slc_tv};
}

bool SourceRuleSet::empty() const
{
	return source_rule_seq.empty();
}

size_t SourceRuleSet::size() const
{
	return source_rule_seq.size();
}

std::string SourceRuleSet::to_string(const std::string& indent) const
{
	std::stringstream ss;
	std::string indent2 = indent + oc_to_string_indent;
	ss << indent << "size = " << source_rule_seq.size();
	size_t i = 0;
	for (const SourceRule& sr : source_rule_seq) {
		ss << std::endl << indent << "(source,rule)[" << i << "]:"
		   << std::endl << sr.to_string(indent2);
		i++;
	}
	return ss.str();
}

std::string oc_to_string(const SourceRule& sr, const std::string& indent)
{
	return sr.to_string(indent);
}

std::string oc_to_string(const SourceRuleSet& srs, const std::string& indent)
{
	return srs.to_string(indent);
}

} // ~namespace opencog