Skip to content

Commit

Permalink
Merge pull request #2571 from linas/bind-queue
Browse files Browse the repository at this point in the history
All search functions now use QueueValue for results.
  • Loading branch information
linas authored May 5, 2020
2 parents f42090d + 2563b6d commit e369a71
Show file tree
Hide file tree
Showing 18 changed files with 173 additions and 69 deletions.
19 changes: 9 additions & 10 deletions opencog/atoms/pattern/BindLink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@
* 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
* 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:
* 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/util/oc_assert.h>
#include <opencog/atoms/atom_types/NameServer.h>
#include <opencog/atoms/core/UnorderedLink.h>
#include <opencog/atomspace/AtomSpace.h>
Expand Down Expand Up @@ -66,24 +65,24 @@ BindLink::BindLink(const HandleSeq&& hseq, Type t)
/** Wrap query results in a SetLink, place them in the AtomSpace. */
ValuePtr BindLink::execute(AtomSpace* as, bool silent)
{
ValueSet rslt(do_execute(as, silent));
QueueValuePtr qv(do_execute(as, silent));
OC_ASSERT(qv->is_closed(), "Unexpected queue state!");
HandleSeq rslt(qv->to_handle_seq());

// If there is an anchor, then attach results to the anchor.
// Otherwise, create a SetLink and return that.
if (_variables._anchor and as)
{
for (const ValuePtr& v: rslt)
as->add_link(MEMBER_LINK, HandleCast(v), _variables._anchor);
for (const Handle& h: rslt)
as->add_link(MEMBER_LINK, h, _variables._anchor);

return _variables._anchor;
}

// The result_set contains a list of the grounded expressions.
// (The order of the list has no significance, so it's really a set.)
// Put the set into a SetLink, cache it, and return that.
HandleSeq hlist;
for (const ValuePtr& v: rslt) hlist.emplace_back(HandleCast(v));
Handle rewr(createUnorderedLink(std::move(hlist), SET_LINK));
Handle rewr(createUnorderedLink(std::move(rslt), SET_LINK));

#define PLACE_RESULTS_IN_ATOMSPACE
#ifdef PLACE_RESULTS_IN_ATOMSPACE
Expand Down
18 changes: 10 additions & 8 deletions opencog/atoms/pattern/GetLink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@
* 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
* 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:
* 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/util/oc_assert.h>
#include <opencog/atoms/atom_types/NameServer.h>
#include <opencog/atoms/core/UnorderedLink.h>
#include <opencog/query/Satisfier.h>
Expand Down Expand Up @@ -48,31 +47,34 @@ GetLink::GetLink(const HandleSeq&& hseq, Type t)

/* ================================================================= */

HandleSet GetLink::do_execute(AtomSpace* as, bool silent)
QueueValuePtr GetLink::do_execute(AtomSpace* as, bool silent)
{
if (nullptr == as) as = _atom_space;

SatisfyingSet sater(as);
this->satisfy(sater);

return sater._satisfying_set;
return sater.get_result_queue();
}

ValuePtr GetLink::execute(AtomSpace* as, bool silent)
{
QueueValuePtr qv(do_execute(as, silent));
OC_ASSERT(qv->is_closed(), "Unexpected queue state!");
HandleSeq hs(qv->to_handle_seq());

// If there is an anchor, then attach results to the anchor.
// Otherwise, create a SetLink and return that.
if (_variables._anchor and as)
{
HandleSet hs(do_execute(as, silent));
for (const Handle& h : hs)
as->add_link(MEMBER_LINK, h, _variables._anchor);

return _variables._anchor;
}

// Create the satisfying set, and cache it.
Handle satset(createUnorderedLink(do_execute(as, silent), SET_LINK));
Handle satset(createUnorderedLink(std::move(hs), SET_LINK));

#define PLACE_RESULTS_IN_ATOMSPACE
#ifdef PLACE_RESULTS_IN_ATOMSPACE
Expand Down
2 changes: 1 addition & 1 deletion opencog/atoms/pattern/GetLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class GetLink : public PatternLink
{
protected:
void init(void);
virtual HandleSet do_execute(AtomSpace*, bool silent);
virtual QueueValuePtr do_execute(AtomSpace*, bool silent);

public:
GetLink(const HandleSeq&&, Type=GET_LINK);
Expand Down
26 changes: 12 additions & 14 deletions opencog/atoms/pattern/QueryLink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <opencog/util/oc_assert.h>
#include <opencog/atoms/atom_types/NameServer.h>
#include <opencog/query/DefaultImplicator.h>
#include <opencog/atoms/value/LinkValue.h>
Expand Down Expand Up @@ -129,7 +130,7 @@ void QueryLink::extract_variables(const HandleSeq& oset)
* atoms that could be a ground are found in the atomspace, then they
* will be reported.
*/
ValueSet QueryLink::do_execute(AtomSpace* as, bool silent)
QueueValuePtr QueryLink::do_execute(AtomSpace* as, bool silent)
{
if (nullptr == as) as = _atom_space;

Expand All @@ -154,12 +155,10 @@ ValueSet QueryLink::do_execute(AtomSpace* as, bool silent)
this->PatternLink::satisfy(impl);

// If we got a non-empty answer, just return it.
if (0 < impl.get_result_set().size())
{
// The result_set contains a list of the grounded expressions.
// (The order of the list has no significance, so it's really a set.)
return impl.get_result_set();
}
QueueValuePtr qv(impl.get_result_queue());
OC_ASSERT(qv->is_closed(), "Unexpected queue state!");
if (0 < qv->size())
return qv;

// If we are here, then there were zero matches.
//
Expand All @@ -180,20 +179,19 @@ ValueSet QueryLink::do_execute(AtomSpace* as, bool silent)
if (0 == pat.mandatory.size() and 0 < pat.optionals.size()
and not intu->optionals_present())
{
ValueSet result;
qv->open();
for (const Handle& himp: impl.implicand)
result.insert(impl.inst.execute(himp, true));
return result;
qv->push(std::move(impl.inst.execute(himp, true)));
qv->close();
return qv;
}

return ValueSet();
return qv;
}

ValuePtr QueryLink::execute(AtomSpace* as, bool silent)
{
// The result_set contains a list of the grounded expressions.
// (The order of the list has no significance, so it's really a set.)
return createLinkValue(do_execute(as, silent));
return do_execute(as, silent);
}

DEFINE_LINK_FACTORY(QueryLink, QUERY_LINK)
Expand Down
3 changes: 2 additions & 1 deletion opencog/atoms/pattern/QueryLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define _OPENCOG_QUERY_LINK_H

#include <opencog/atoms/pattern/PatternLink.h>
#include <opencog/atoms/value/QueueValue.h>

namespace opencog
{
Expand All @@ -42,7 +43,7 @@ class QueryLink : public PatternLink
// will initialize the rewrite term _implicand.
void extract_variables(const HandleSeq& oset);

virtual ValueSet do_execute(AtomSpace*, bool silent);
virtual QueueValuePtr do_execute(AtomSpace*, bool silent);

public:
QueryLink(const HandleSeq&&, Type=QUERY_LINK);
Expand Down
16 changes: 16 additions & 0 deletions opencog/atoms/value/LinkValue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,27 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <opencog/atoms/base/Atom.h>
#include <opencog/atoms/value/LinkValue.h>
#include <opencog/atoms/value/ValueFactory.h>

using namespace opencog;


HandleSeq LinkValue::to_handle_seq(void) const
{
update();
HandleSeq hs;
for (const ValuePtr& v : _value)
{
if (v->is_atom())
hs.push_back(HandleCast(v));
}
return hs;
}

// ==============================================================

bool LinkValue::operator==(const Value& other) const
{
if (LINK_VALUE != other.get_type()) return false;
Expand Down
2 changes: 2 additions & 0 deletions opencog/atoms/value/LinkValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <vector>
#include <opencog/atoms/value/Value.h>
#include <opencog/atoms/base/Handle.h>
#include <opencog/atoms/atom_types/atom_types.h>

namespace opencog
Expand Down Expand Up @@ -57,6 +58,7 @@ class LinkValue
virtual ~LinkValue() {}

const std::vector<ValuePtr>& value() const { update(); return _value; }
HandleSeq to_handle_seq(void) const;

/** Returns a string representation of the value. */
virtual std::string to_string(const std::string& indent = "") const;
Expand Down
5 changes: 5 additions & 0 deletions opencog/atoms/value/QueueValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ typedef std::shared_ptr<QueueValue> QueueValuePtr;
static inline QueueValuePtr QueueValueCast(ValuePtr& a)
{ return std::dynamic_pointer_cast<QueueValue>(a); }

template<typename ... Type>
static inline std::shared_ptr<QueueValue> createQueueValue(Type&&... args) {
return std::make_shared<QueueValue>(std::forward<Type>(args)...);
}

/** @}*/
} // namespace opencog

Expand Down
47 changes: 33 additions & 14 deletions opencog/query/Implicator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@

using namespace opencog;

Implicator::Implicator(AtomSpace* as)
: _as(as), inst(as), max_results(SIZE_MAX)
{
}

/**
* This callback takes the reported grounding, runs it through the
* instantiator, to create the implicand, and then records the result
Expand Down Expand Up @@ -64,21 +69,35 @@ bool Implicator::grounding(const GroundingMap &var_soln,
return (_result_set.size() >= max_results);
}

void Implicator::insert_result(const ValuePtr& v)
void Implicator::insert_result(ValuePtr v)
{
if (v and _result_set.end() == _result_set.find(v))
{
// Insert atom into the atomspace immediately, so that
// it becomes visible in other threads.
if (v->is_atom())
{
_result_set.insert(_as->add_atom(HandleCast(v)));
}
else
{
_result_set.insert(v);
}
}
if (nullptr == v) return;
if (_result_set.end() != _result_set.find(v)) return;

// Insert atom into the atomspace immediately, so that
// it becomes visible in other threads.
if (v->is_atom())
v = _as->add_atom(HandleCast(v));

if (_result_set.end() != _result_set.find(v)) return;

_result_set.insert(v);
_result_queue->push(std::move(v));
}

bool Implicator::start_search(void)
{
// *Every* search gets a brand new, fresh queue!
// This allows users to hang on to the old queue, holding
// previous results, if they need to.
_result_queue = createQueueValue();
return false;
}

bool Implicator::search_finished(bool done)
{
_result_queue->close();
return done;
}

/* ===================== END OF FILE ===================== */
13 changes: 9 additions & 4 deletions opencog/query/Implicator.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <opencog/atomspace/AtomSpace.h>

#include <opencog/atoms/execution/Instantiator.h>
#include <opencog/atoms/value/QueueValue.h>
#include <opencog/query/PatternMatchCallback.h>


Expand Down Expand Up @@ -58,19 +59,23 @@ class Implicator :
AtomSpace* _as;

ValueSet _result_set;
void insert_result(const ValuePtr&);
QueueValuePtr _result_queue;
void insert_result(ValuePtr);

public:
Implicator(AtomSpace* as) : _as(as), inst(as), max_results(SIZE_MAX) {}
Implicator(AtomSpace*);
Instantiator inst;
HandleSeq implicand;
size_t max_results;

virtual bool grounding(const GroundingMap &var_soln,
const GroundingMap &term_soln);

virtual const ValueSet& get_result_set() const
{ return _result_set; }
virtual bool start_search(void);
virtual bool search_finished(bool);

virtual QueueValuePtr get_result_queue()
{ return _result_queue; }
};

}; // namespace opencog
Expand Down
6 changes: 5 additions & 1 deletion opencog/query/PatternLinkRuntime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -429,9 +429,13 @@ bool PatternLink::satisfy(PatternMatchCallback& pmcb) const
GroundingMap empty_vg;
GroundingMap empty_pg;
pmcb.set_pattern(_variables, _pat);
return recursive_virtual(pmcb, _virtual, _pat.optionals,
bool done = pmcb.start_search();
if (done) return done;
done = recursive_virtual(pmcb, _virtual, _pat.optionals,
empty_vg, empty_pg,
comp_var_gnds, comp_term_gnds);
done = pmcb.search_finished(done);
return done;
}

/* ===================== END OF FILE ===================== */
Loading

0 comments on commit e369a71

Please sign in to comment.