Skip to content

Commit

Permalink
Add FindType rpc to get the type of an atom given its name
Browse files Browse the repository at this point in the history
  • Loading branch information
Habush committed Sep 15, 2020
1 parent 60479d3 commit 7b01ef1
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 68 deletions.
3 changes: 3 additions & 0 deletions specs/atom_server.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ service AtomServer {

//Find nodes with similar names to a given node. Currently it uses a simple regex and limits the result to 10
rpc FindSimilar(AtomRequest) returns (stream NodeMsg);

//Given an atom name, return the atom type if it exists
rpc FindType(PatternMsg) returns (NodeMsg);
}
16 changes: 16 additions & 0 deletions src/AtomServiceClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ void AtomServiceClient::FindSimilar(const std::string &atom_id, const std::strin
}
}

NodeMsg AtomServiceClient::FindType(const std::string &atom_id, const std::string &name) {
ClientContext context;
PatternMsg msg;
NodeMsg nodeMsg;

msg.set_atomspace(atom_id);
msg.set_query(name);

Status status = _stub->FindType(&context, msg, &nodeMsg);
if(!status.ok()){
throw std::runtime_error("FindType rpc failed. Reason: " + status.error_message());
}

return nodeMsg;
}

Handle AtomServiceClient::FromNodeMsg(const NodeMsg &node) {
Type type = nameserver().getType(node.type());
return createNode(type, std::move(node.name()));
Expand Down
8 changes: 8 additions & 0 deletions src/AtomServiceClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ class AtomServiceClient {
void FindSimilar(const std::string &atom_id, const std::string &type_name, const std::string
&node_name, HandleSeq& result, AtomSpace* as);

/**
* Return all the handles with a specific name in atomspace atom_id
* @param atom_id - the id of the remote atomspace
* @param name - he name of the node
* @param result - NodeMsg representing the handle
*/
NodeMsg FindType(const std::string &atom_id, const std::string &name);

private:
Handle FromNodeMsg(const NodeMsg& node);
Handle FromLinkMsg(const LinkMsg& link);
Expand Down
18 changes: 18 additions & 0 deletions src/AtomspaceService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,27 @@ class AtomServerImpl final : public AtomServer::Service {
return Status::OK;
}

Status FindType(ServerContext* context, const PatternMsg* request, NodeMsg *nodeMsg) override{
try {
Handle h = _atomManager.findType(request->atomspace(), request->query());
nodeMsg->CopyFrom(buildNodeMsg(h));
} catch(std::runtime_error& err) {
std::cout << "Error: " << err.what() << std::endl;
return Status(StatusCode::CANCELLED, err.what());
}

return Status::OK;
}

private:

NodeMsg buildNodeMsg(const Handle &h) {
NodeMsg nodeMsg;
if(h == Handle::UNDEFINED){
nodeMsg.set_type("undefined");
nodeMsg.set_name("");
return nodeMsg;
}
nodeMsg.set_type(nameserver().getTypeName(h->get_type()));
nodeMsg.set_name(h->get_name());
return nodeMsg;
Expand All @@ -123,6 +140,7 @@ class AtomServerImpl final : public AtomServer::Service {
}

AtomSpaceManager _atomManager;
std::mutex _mu;
};

void RunServer(const std::string &fname, const std::string &addr) {
Expand Down
100 changes: 91 additions & 9 deletions src/guile/AtomServiceSCM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,44 @@
#include <string>
#include <memory>
#include <opencog/guile/SchemeModule.h>
#include <opencog/guile/SchemePrimitive.h>
#include <libguile.h>
#include <AtomServiceClient.h>

using namespace opencog;

class AtomServiceSCM;

//Special case where the returned type is SCM type.
//Note: I had to add this custom class because using SchemePrimitive<SCM, C, Args...> call to member function 'scm_from' is ambiguous
//with candidate functions SCM scm_from(SCM scm) const and SCM scm_from(bool b) const
template<typename C, class... Args>
class CustomSchemePrimitive: public SchemePrimitiveBase<SCM, C, Args...> {
typedef SchemePrimitiveBase<SCM, C, Args...> super;
public:
CustomSchemePrimitive(const char* module, const char* name,
SCM(C::*cb)(Args...), C *data): super(module, name, cb, data){}

protected:
// Convert any type to SCM
SCM scm_from(SCM scm) const
{
return scm;
}

SCM invoke (SCM args) override {
return scm_from(super::cpp_invoke(args));
}
};

template<typename C, class... Args>
inline void define_scheme_custom_primitive(const char *name,
SCM (C::*method)(Args...),
C *data,
const char* module= "extension")
{
new CustomSchemePrimitive(module, name, method, data);
}


class AtomServiceSCM : public ModuleWrap {
public:
Expand All @@ -23,9 +57,12 @@ class AtomServiceSCM : public ModuleWrap {
HandleSeq FindSimilar(const std::string &atom_id, const std::string &type_name, const std::string
&node_name);

SCM FindType(const std::string& atom_id, SCM lst);

private:
void init(void);

//Re-definition of opencog::SchemeSmob::scm_to_string_list as that one has a private access
static std::vector<std::string> scm_to_string_list(SCM lst);
std::shared_ptr<grpc::Channel> _channel;
};

Expand Down Expand Up @@ -55,6 +92,19 @@ AtomServiceSCM::AtomServiceSCM(void)
module_init();
}

void AtomServiceSCM::init(void) {
define_scheme_primitive("exec-pattern",
&AtomServiceSCM::ExecutePattern, this, "grpc");

define_scheme_primitive("check-node",
&AtomServiceSCM::CheckNode, this, "grpc");

define_scheme_primitive("find-similar-node",
&AtomServiceSCM::FindSimilar, this, "grpc");

define_scheme_custom_primitive("find-type", &AtomServiceSCM::FindType, this, "grpc");
}

HandleSeq AtomServiceSCM::ExecutePattern(const std::string &atom_id, const Handle &patt) {
if(patt->is_executable()){
HandleSeq res;
Expand Down Expand Up @@ -85,15 +135,47 @@ HandleSeq AtomServiceSCM::FindSimilar(const std::string &atom_id, const std::str
return res;
}

void AtomServiceSCM::init(void) {
define_scheme_primitive("exec-pattern",
&AtomServiceSCM::ExecutePattern, this, "grpc");
/**
* Find the atoms representing the list of string names
* @param atom_id - the atomspace id
* @param lst - list of names that we want to search for
* @return
*/
SCM AtomServiceSCM::FindType(const std::string& atom_id, SCM lst) {
AtomServiceClient client(_channel);
// std::string id(scm_to_utf8_string(atom_id));
std::vector<std::string> names = scm_to_string_list(lst);

SCM result = SCM_EOL;
NodeMsg msg;
for(auto &name: names){
msg = client.FindType(atom_id, name);
if(msg.type() == "undefined"){
result = scm_acons(scm_from_utf8_string(name.c_str()), SCM_BOOL_F, result);
} else{
result = scm_acons(scm_from_utf8_string(name.c_str()), scm_from_utf8_string(msg.type().c_str()), result);
}
}

define_scheme_primitive("check-node",
&AtomServiceSCM::CheckNode, this, "grpc");
return result;

define_scheme_primitive("find-similar-node",
&AtomServiceSCM::FindSimilar, this, "grpc");
}


std::vector<std::string> AtomServiceSCM::scm_to_string_list (SCM svalue_list)
{
std::vector<std::string> out;
SCM sl = svalue_list;
while (scm_is_pair(sl)) {
SCM svalue = SCM_CAR(sl);

if (not scm_is_null(svalue)) {
char * v = scm_to_utf8_string(svalue);
out.emplace_back(v);
}
sl = SCM_CDR(sl);
}
return out;
}

void opencog_atom_service_init(void) {
Expand Down
110 changes: 60 additions & 50 deletions src/manager/AtomSpaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
#include "AtomSpaceManager.h"
#include "Timer.h"

static NameServer& namer = nameserver();

AtomSpacePtr AtomSpaceManager::loadAtomSpace(const std::string &fname, const std::string &id) {
//Check if the id exists
auto res = _atomspaceMap.find(id);
Expand All @@ -27,7 +25,6 @@ AtomSpacePtr AtomSpaceManager::loadAtomSpace(const std::string &fname, const std
AtomSpacePtr atomspace = std::make_shared<AtomSpace>();

load_file(fname, *atomspace);

return atomspace;

}
Expand All @@ -50,53 +47,6 @@ AtomSpacePtr AtomSpaceManager::loadDirectory(const std::string &dirname, const s
return atomspace;
}


bool AtomSpaceManager::removeAtomSpace(const std::string &id) {
auto res = _atomspaceMap.find(id);
if (res == _atomspaceMap.end()) {
return false;
}

_atomspaceMap.erase(id);
_atomIds.erase(std::remove(_atomIds.begin(), _atomIds.end(), id));
return true;

}


Handle AtomSpaceManager::executePattern(const std::string &id, const std::string &pattern) const {
auto res = _atomspaceMap.find(id);
if (res == _atomspaceMap.end()) {
throw std::runtime_error("An Atomspace with id " + id + " not found");
}

Handle h;
AtomSpacePtr atomspace = res->second;

try {
h = opencog::parseExpression(pattern, *atomspace);
} catch (std::runtime_error &err) {
throw err;
}

if (h == nullptr) {
throw std::runtime_error("Invalid Pattern Matcher query: " + pattern);
}

Handle result;
if (h->is_executable()) {

ValuePtr pattResult = h->execute(atomspace.get());
result = std::dynamic_pointer_cast<Atom>(pattResult);
return result;

} // not a pattern matching query
atomspace->remove_atom(h, true);
throw std::runtime_error("Only send pattern matching query to execute patterns. " + pattern + " is not a "
"pattern matching query");

}

std::vector<std::string> AtomSpaceManager::getAtomspaces() const {
return _atomIds;
}
Expand Down Expand Up @@ -137,6 +87,34 @@ void AtomSpaceManager::loadFromSettings(const std::string &fname) {

}

bool AtomSpaceManager::removeAtomSpace(const std::string &id) {
auto res = _atomspaceMap.find(id);
if (res == _atomspaceMap.end()) {
return false;
}

_atomspaceMap.erase(id);
_atomIds.erase(std::remove(_atomIds.begin(), _atomIds.end(), id));
return true;


}

Handle AtomSpaceManager::findType(const std::string &id, const std::string &name) {
HandleSeq res;
AtomSpacePtr atomSpacePtr = _atomspaceMap.at(id);
std::string type_name;
for(Type type: _types){
type_name = namer.getTypeName(type);
Handle h = atomSpacePtr->get_handle(type, name);
if(h != Handle::UNDEFINED){
return h;
}
}

return Handle::UNDEFINED;
}

Handle AtomSpaceManager::findNode(const std::string& type_name, const std::string &name, const std::string& id) {
AtomSpacePtr as = getAtomspace(id);
if(as == nullptr){
Expand Down Expand Up @@ -181,3 +159,35 @@ void AtomSpaceManager::findSimilarNames(const std::string &id, const std::string
// return h->get_name();
// });
}

Handle AtomSpaceManager::executePattern(const std::string &id, const std::string &pattern) const {
auto res = _atomspaceMap.find(id);
if (res == _atomspaceMap.end()) {
throw std::runtime_error("An Atomspace with id " + id + " not found");
}

Handle h;
AtomSpacePtr atomspace = res->second;

try {
h = opencog::parseExpression(pattern, *atomspace);
} catch (std::runtime_error &err) {
throw err;
}

if (h == nullptr) {
throw std::runtime_error("Invalid Pattern Matcher query: " + pattern);
}

Handle result;
if (h->is_executable()) {

ValuePtr pattResult = h->execute(atomspace.get());
result = std::dynamic_pointer_cast<Atom>(pattResult);
return result;

} // not a pattern matching query
atomspace->remove_atom(h, true);
throw std::runtime_error("Only send pattern matching query to execute patterns. " + pattern + " is not a "
"pattern matching query");
}
12 changes: 10 additions & 2 deletions src/manager/AtomSpaceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ using json = nlohmann::json;
typedef std::shared_ptr<AtomSpace> AtomSpacePtr;

typedef std::map<std::string, AtomSpacePtr> AtomSpaceMap;
typedef std::vector<Type> TypeList;
static NameServer& namer = nameserver();

class AtomSpaceManager {

public:
AtomSpaceManager() {};
AtomSpaceManager() {
namer.getChildrenRecursive(CONCEPT_NODE, std::back_inserter(_types));
_types.push_back(CONCEPT_NODE);
}

~AtomSpaceManager() = default;

Expand All @@ -46,13 +51,16 @@ class AtomSpaceManager {

Handle findNode(const std::string& type_name, const std::string &name, const std::string &id);

//Given a name, return atoms with that name
Handle findType(const std::string& id, const std::string &name);

void findSimilarNames(const std::string &id, const std::string& type_name, const std::string &name,
HandleSeq &result);

private:
AtomSpaceMap _atomspaceMap;
std::vector<std::string> _atomIds;

TypeList _types;
};


Expand Down
Loading

0 comments on commit 7b01ef1

Please sign in to comment.