-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A sketch of DAS integration #446
Changes from 5 commits
5e99a16
a8b3100
e927a76
330fc56
82d4b6e
9350972
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
from hyperon import * | ||
from hyperon.ext import register_atoms | ||
|
||
import os | ||
import re | ||
import json | ||
|
||
from hyperon_das import DasAPI | ||
from hyperon_das.das import QueryOutputFormat as Format | ||
from hyperon_das.pattern_matcher import ( | ||
Link, | ||
Node, | ||
Variable, | ||
And, | ||
Or, | ||
Not, | ||
PatternMatchingAnswer, | ||
) | ||
|
||
class DASpace(AbstractSpace): | ||
|
||
def __init__(self, unwrap=True): | ||
super().__init__() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not technically needed since AbstractSpace is pure-virtual, but also harmless. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I see. I'd still keep it here, because if some useful functionality is introduced in the parent class, then it will not be missed in DASpace as well. I'm also ok to remove it if |
||
self.das = DasAPI('hash_table') | ||
self.unwrap = unwrap | ||
|
||
def _atom2dict(self, atom): | ||
if isinstance(atom, ExpressionAtom): | ||
return { | ||
"type": "Expression", | ||
"targets": [self._atom2dict(ch) for ch in atom.get_children()] | ||
} | ||
else: | ||
return { | ||
"type": "Symbol", | ||
"name": repr(atom) | ||
} | ||
|
||
def _atom2query(self, atom): | ||
if isinstance(atom, ExpressionAtom): | ||
targets = atom.get_children() | ||
if isinstance(targets[0], SymbolAtom) and targets[0].get_name() == ',': | ||
return And([self._atom2query(ch) for ch in targets[1:]]) | ||
return Link("Expression", ordered=True, | ||
targets=[self._atom2query(ch) for ch in targets]) | ||
else: | ||
if isinstance(atom, VariableAtom): | ||
return Variable(repr(atom)) | ||
else: | ||
return Node("Symbol", repr(atom)) | ||
|
||
def _handle2atom(self, h): | ||
try: | ||
return S(self.das.get_node_name(h)) | ||
except Exception as e: | ||
return E(*[self._handle2atom(ch) for ch in self.das.get_link_targets(h)]) | ||
|
||
def query(self, query_atom): | ||
query = self._atom2query(query_atom) | ||
answer = PatternMatchingAnswer() | ||
new_bindings_set = BindingsSet.empty() | ||
if not query.matched(self.das.db, answer): | ||
return new_bindings_set | ||
for a in answer.assignments: | ||
bindings = Bindings() | ||
for var, val in a.mapping.items(): | ||
# remove '$', because it is automatically added | ||
bindings.add_var_binding(V(var[1:]), self._handle2atom(val)) | ||
new_bindings_set.push(bindings) | ||
return new_bindings_set | ||
|
||
def add(self, atom): | ||
dc = self._atom2dict(atom) | ||
if "name" in dc: | ||
self.das.add_node(dc) | ||
else: | ||
self.das.add_link(dc) | ||
|
||
#def remove(self, atom): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without Do we want to modify the Space contract so that a Space can gracefully decline to implement these functions in the same way a Space can decline to implement It seems to me that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is perfectly ok.
What behavior will be in this case for
Do you mean that if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Does it really work by this way? I believe the exception should be wrapped into |
||
# pass | ||
#def replace(self, from_atom, to_atom): | ||
# pass | ||
#def atom_count(self): | ||
# return self.das.count_atoms() | ||
#def atoms_iter(self): | ||
# return iter(self.atoms_list) | ||
|
||
@register_atoms(pass_metta=True) | ||
def das_atoms(metta): | ||
newDASpaceAtom = OperationAtom('new-das', lambda: [G(SpaceRef(DASpace()))], unwrap=False) | ||
return { | ||
r"new-das": newDASpaceAtom, | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
!(extend-py! dasgate) | ||
|
||
!(bind! &das (new-das)) | ||
|
||
!(add-atom &das (Test (Test 2))) | ||
!(add-atom &das (Best (Test 2))) | ||
!(add-atom &das Test) | ||
|
||
; The simplest match with grounding the variable in the node | ||
!(match &das ($v1 (Test 2)) (This $v1 works)) | ||
; The simplest match with grounding the variable in the link | ||
!(match &das (Test $v2) (This $v2 works)) | ||
|
||
!(add-atom &das (Rest (Test 3))) | ||
!(add-atom &das (Test (Test 3))) | ||
|
||
; Compositional (And) query test | ||
!(match &das (, (Best $x) ($v $x)) ($v $x)) | ||
; !(match &das (, ($v1 $x) (Test $x)) ($v1 Test $x)) | ||
|
||
; !(match &das ($v1 ($v2 2)) (This $v1 works)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe include instructions about where to find the
hyperon_das
module / or how to setup & run / connect to the DAS more generallyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, their repo is private now, so this PR was more for information than for the in-depth review. Of course, the link to DAS will be provided, once it is open.