Skip to content
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

[WIP] KnowledgeBase-Channel (WordNet) #34

Draft
wants to merge 6 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions pynars/NARS/Channels/WordNetChannel/WordNetChannel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""
Compatible with BufferMC.

ChannelMC (the old one) class is kept there for further changes.
"""
import re

from nltk.corpus import wordnet as wn

from pynars.Narsese import parser


def convert_util(sentence: str):
if len(re.findall("[a-zA-Z0-9]+", sentence)) == 1:
return sentence
else:
return "\"" + sentence + "\""


def word2narsese(word: str):
"""
Two stages:
1) pre-synset processing: build links between i) word and its own synsets, ii) word and its synonyms, iii) word's
synonyms and their synsets
2) synset processing: build links between i) synset and its related synsets, ii) synset and its lemmas, iii)
lemmas with their antonyms (with a higher priority)
:return: list[str]
"""

ret = []

# stage 1
# ==================================================================================================================

synsets = [] # for stage 2 processing

synonyms = wn.synonyms(word) # get synonyms first, they are word-level (not give in synsets)
# build links between word and its synonyms
for synonym in synonyms:
if len(synonym) != 0:
for each_synonym in synonym:
# synonym
ret.append(parser.parse("<" + convert_util(word) + " <-> " + convert_util(each_synonym) + ">."))
for each_synonym_synset in wn.synsets(each_synonym):
synsets.append(each_synonym_synset) # add to stage 2 processing
synset_t = convert_util(each_synonym_synset.name()) # synset term
ret.append(parser.parse("<" + synset_t + " --> " + convert_util(each_synonym) + ">."))

# build links between word and its synsets
for each_synset in wn.synsets(word):
synsets.append(each_synset) # add to stage 2 processing
synset_t = convert_util(each_synset.name()) # synset term
ret.append(parser.parse("<" + synset_t + " --> " + convert_util(word) + ">."))

# stage 2
# ==================================================================================================================

for synset in synsets:

synset_t = convert_util(synset.name()) # synset term

for each in synset.hypernyms(): # hypernyms
ret.append(parser.parse("<" + synset_t + " --> " + convert_util(each.name()) + ">."))
for each in synset.hyponyms(): # hyponyms
ret.append(parser.parse("<" + convert_util(each.name()) + " --> " + synset_t + ">."))
for each in synset.instance_hypernyms(): # instance hypernyms
ret.append(parser.parse("<{" + synset_t + "} --> " + convert_util(each.name()) + ">."))
for each in synset.instance_hyponyms(): # instance hyponyms
ret.append(parser.parse("<{" + convert_util(each.name()) + "} --> " + synset_t + ">."))
for each in synset.member_holonyms(): # member holonyms
ret.append(parser.parse("<(*," + convert_util(each.name()) + "," + synset_t + ") --> MemberOf>."))
for each in synset.substance_holonyms(): # substance holonyms
ret.append(parser.parse("<(*," + convert_util(each.name()) + "," + synset_t + ") --> SubstanceOf>."))
for each in synset.part_holonyms(): # part holonyms
ret.append(parser.parse("<(*," + convert_util(each.name()) + "," + synset_t + ") --> PartOf>."))
for each in synset.member_meronyms(): # member meronyms
ret.append(parser.parse("<(*," + synset_t + "," + convert_util(each.name()) + ") --> MemberOf>."))
for each in synset.substance_meronyms(): # substance meronyms
ret.append(parser.parse("<(*," + synset_t + "," + convert_util(each.name()) + ") --> SubstanceOf>."))
for each in synset.part_meronyms(): # part meronyms
ret.append(parser.parse("<(*," + synset_t + "," + convert_util(each.name()) + ") --> PartOf>."))
for each in synset.attributes(): # attributes
ret.append(parser.parse("<(&," + convert_util(each.name()) + "," + synset_t + ") --> " + synset_t + ">."))
for each in synset.entailments(): # entailments
ret.append(parser.parse("<(*," + convert_util(each.name()) + "," + synset_t + ") --> After>."))
for each in synset.causes(): # causes
ret.append(parser.parse("<(*," + synset_t + "," + convert_util(each.name()) + ") --> After>."))
for each in synset.also_sees(): # also sees
ret.append(parser.parse("<(*," + synset_t + "," + convert_util(each.name()) + ") --> SameTime>."))
for each in synset.verb_groups(): # verb groups
ret.append(parser.parse("<" + synset_t + " <-> " + convert_util(each.name()) + ">."))
for each in synset.similar_tos(): # similar-to's
ret.append(parser.parse("<" + synset_t + " <-> " + convert_util(each.name()) + ">."))

lemmas = synset.lemmas()
for lemma in lemmas: # lemmas
lemma_t = convert_util(lemma.name())
ret.append(parser.parse("<" + lemma_t + " --> " + synset_t + ">."))
for antonym in lemma.antonyms(): # antonyms, higher priority
ret.append(parser.parse(
"$0.9; 0.9; 0.5$ <" + convert_util(antonym.name()) + " <-> " + lemma_t + ">. %0.0; 0.9%"))

return ret


class WordNetChannel:

def __init__(self, ID, buffer):
self.ID = ID
self.buffer = buffer

def WordNetQuery(self, task=None):
"""
Query WordNet with a single natural language word. Can be an empty query, if so, then it will pop previous
remaining queries.
"""
tasks = []
if task is not None and task.is_goal:

try:
"""
Something is wrong with the variable related functionalities.
Here is a relatively fixed format extracting the query word.
"""
query_word = \
[x.word for x in task.term.subject.sub_terms if
x.word != "WordNet" and x.word != task.term.subject.word][0]
tasks = word2narsese(query_word)
except:
tasks = []

return self.buffer.buffer_cycle(tasks)
Empty file.
95 changes: 95 additions & 0 deletions pynars/NARS/Channels/WordNetChannel/draft2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
"""
draft2.py uses wordnet as an example
"""


from multiprocessing import Process

from .WordNetChannel import WordNetChannel
from pynars.NARS import Reasoner
from pynars.Narsese import Task
from pynars.NARS.DataStructures.MC.util.word2narsese_exAll import words2narsese


def nars_core():
"""
It will try to read from the nars_inputs list, and write the results in nars_outputs (just write for recording).
And it will also append some results to wcn_inputs for further processing. (hand the task to the channel)
"""
global nars_input
global nars_output
global wch_input
global wch_output
for _ in range(300):
# here it runs for 300 cycles, but it is designed to run forever, if so, please use while(True)
if len(nars_input) == 0:
ret = nars.cycle()
else:
tmp = nars_input.pop(0)

print("narsese input:", tmp)

if isinstance(tmp, Task):
success, task, _, ret = nars.input_narsese(text=str(tmp), go_cycle=True)
else:
success, task, _, ret = nars.input_narsese(text=tmp, go_cycle=True)
nars_output.append(ret)
if len(ret[0]) != 0:
for each in ret[0]:
wch_input.append(each)


def wcn_core():
global nars_input
global nars_output
global wch_input
global wch_output
for _ in range(300):
# here it runs for 300 cycles, but it is designed to run forever, if so, please use while(True)
if len(wch_input) == 0:
ret = wcn.WordNetQuery()
else:
tmp = wch_input.pop(0)
print("channel input:", tmp)
ret = wcn.WordNetQuery(tmp)
wch_output.append(ret)
if ret is not None:
nars_input.append(each)


if __name__ == "__main__":

apriori_knowledge = ["<Query(WordNet, $x) ==> <$x --> [KNOWN]>>.",
"<<$label --> X> ==> <$label --> [pos]>>. %0.6;0.99%",
"<explosion --> X>.",
"<car --> X>.",
"<accident --> X>."] # note this X is for one single case

nars = Reasoner(1000, 1000)
for each in apriori_knowledge:
nars.input_narsese(each, True)

buff = Buffer(100, nars.memory)
wcn = WordNetChannel("WCN", buff)

# global data
nars_input = ["<X --> [KNOWN]>!", "<?1 --> [pos]>?"]
nars_output = []
wch_input = []
wch_output = []

process_list = []

p = Process(target=nars_core(), args=('Python',))
p.start()
process_list.append(p)

p = Process(target=wcn_core(), args=('Python',))
p.start()
process_list.append(p)

for i in range(len(process_list)):
process_list[i].join()

print(nars_output)
print(wch_output)
Loading
Loading