diff --git a/.gitignore b/.gitignore index fd5fbd4..b915704 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ __pycache__/ *$py.class Tests/*.png *.pkl -./utils/SparseLUT +!pynars/utils/SparseLUT/*.pyd temp/ # C extensions *.so diff --git a/.vscode/launch.json b/.vscode/launch.json index 139a611..aa0a219 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -197,7 +197,7 @@ "module": "pynars.Console", "console": "integratedTerminal", "args": [ - "Tests/examples/single_step/nal7/nal7.7.nal" + "Tests/examples/single_step/nal7/nal7.revrev.nal" // "Tests/examples/single_step/nal5.query.nal" ] }, @@ -205,7 +205,7 @@ "name": "Python: _generate_init_file", "type": "python", "request": "launch", - "module": "NAL._generate_init_file" + "module": "pynars.NAL._generate_init_file" }, { "name": "Python: Parser test", diff --git a/README.md b/README.md index f023bbd..9d70ce3 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ Reference: - Python version: 3.7.10. - Only tested under this version, however, Python 3.7 and higher versions maybe acceptable. - OS: Windows 10. - - Only tested under this OS, however, other OS might be ok. + - Only tested under this OS, however, other OSs might be ok. - Packages Requirements: see `requirements.txt`. - - It is noted that the version of the python package `tqdm` should be no higher than 3.1.4, otherwise the color display would be abnormal. This is because of a bug of `tqdm`, which leads to conflicts between `sty` and `tqdm` and cause unexpected color display of `sty`. However, this constraints is not necessary, i.e., higher version of `tqdm` is ok if you don't mind abnormal display occuring. The abnormal case only occur when you first run the PyNARS when SparseLUT (Sparse Look-Up Table) is built. + - It is noted that the version of the python package `tqdm` should be no higher than 3.1.4, otherwise the color display would be abnormal. This is because of a bug of `tqdm`, which leads to conflicts between `sty` and `tqdm` and cause unexpected color display of `sty`. However, this constraints is not necessary, i.e., higher version of `tqdm` is ok if you don't mind abnormal display occuring. The abnormal case only occurs if you first run PyNARS when SparseLUT (Sparse Look-Up Table) is built. #### Installation diff --git a/Tests/examples/single_step/nal7.36.1.nal b/Tests/examples/single_step/nal7.36.1.nal new file mode 100644 index 0000000..9811730 --- /dev/null +++ b/Tests/examples/single_step/nal7.36.1.nal @@ -0,0 +1,12 @@ +'********** deduction with interval summation + +' a + 1 = b +<(&/, a, +1) =/> (&/, b, c)>. + +' b + 1 = c +<(&/, b, c, +1) =/> d>. + +10 + +' a + 2 = c +''outputMustContain('<(&/,a,+2) =/> d>. %1.00;0.81%') diff --git a/Tests/examples/single_step/nal7.36.2.nal b/Tests/examples/single_step/nal7.36.2.nal new file mode 100644 index 0000000..dc59ebf --- /dev/null +++ b/Tests/examples/single_step/nal7.36.2.nal @@ -0,0 +1,12 @@ +'********** deduction with interval summation + +' a + 1 = b +<(&/, a, +1) =/> (&/, b, c)>. + +' b + 1 = c +<(&/, c, b, +1) =/> d>. + +10 + +' a + 2 = c +''outputMustNotContain('<(&/,a,+2) =/> d>. %1.00;0.81%') \ No newline at end of file diff --git a/Tests/examples/single_step/nal7/nal7.18.const.nal b/Tests/examples/single_step/nal7/nal7.18.const.nal new file mode 100644 index 0000000..f277077 --- /dev/null +++ b/Tests/examples/single_step/nal7/nal7.18.const.nal @@ -0,0 +1,14 @@ +'********** inference on tense + +'If someone hold key_101, he will enter room_101 (in 100 steps) +<(&/,<(*, John, key_101) --> hold>,+100) =/> <(*, John, room_101) --> enter>>. + +'John held the key_101 +<(*, John, key_101) --> hold>. :\: + +20 + +'John will enter room_101 +''outputMustContain('<(*,John,room_101) --> enter>. :!95: %1.00;0.81%') + +'this one is working, but throws an exception diff --git a/Tests/examples/single_step/nal7/nal7.18.nal b/Tests/examples/single_step/nal7/nal7.18.var.nal similarity index 100% rename from Tests/examples/single_step/nal7/nal7.18.nal rename to Tests/examples/single_step/nal7/nal7.18.var.nal diff --git a/Tests/examples/single_step/nal7/nal7.19.const.nal b/Tests/examples/single_step/nal7/nal7.19.const.nal new file mode 100644 index 0000000..1fd76c3 --- /dev/null +++ b/Tests/examples/single_step/nal7/nal7.19.const.nal @@ -0,0 +1,12 @@ +'********** inference on tense + +'If someone hold key_101, he will enter room_101 (in 100 steps) +<(&/,<(*, John, key_101) --> hold>,+100) =/> <(*, John, room_101) --> enter>>. + +'John is entering room_101 now +<(*,John,room_101) --> enter>. :|: + +25 + +'John held the key_101 (105 steps before) +''outputMustContain('<(*,John,key_101) --> hold>. :!-105: %1.00;0.45%') diff --git a/Tests/examples/single_step/nal7/nal7.19.nal b/Tests/examples/single_step/nal7/nal7.19.var.nal similarity index 100% rename from Tests/examples/single_step/nal7/nal7.19.nal rename to Tests/examples/single_step/nal7/nal7.19.var.nal diff --git a/Tests/examples/single_step/nal7/nal7.3.nal b/Tests/examples/single_step/nal7/nal7.3.nal index a9200ff..75039d9 100644 --- a/Tests/examples/single_step/nal7/nal7.3.nal +++ b/Tests/examples/single_step/nal7/nal7.3.nal @@ -6,7 +6,7 @@ 'John entered room_101 <(*,John,room_101) --> enter>. :\: %1.00;0.90% -3 +10 ''outputMustContain('<(*,John,key_101) --> hold>. :!-10: %1.00;0.45%') diff --git a/Tests/examples/single_step/nal7/nal7.6.const.nal b/Tests/examples/single_step/nal7/nal7.6.const.nal new file mode 100644 index 0000000..646c645 --- /dev/null +++ b/Tests/examples/single_step/nal7/nal7.6.const.nal @@ -0,0 +1,18 @@ +'********** induction on events + +'John is opening door_101 + (/,open,_,door_101)>. :|: + +6 + +'John is entering room_101 + (/,enter,_,room_101)>. :|: + +20 + +'If John enter room_101, he should open door_101 before +''outputMustContain('< (/,enter,_,room_101)> =\> (&/, (/,open,_,door_101)>,+6)>. :!6: %1.00;0.45%') + +'adjusted +2 to +3 in both conditions + +10 diff --git a/Tests/examples/single_step/nal7/nal7.6.nal b/Tests/examples/single_step/nal7/nal7.6.var.nal similarity index 71% rename from Tests/examples/single_step/nal7/nal7.6.nal rename to Tests/examples/single_step/nal7/nal7.6.var.nal index a9aec70..3db7591 100644 --- a/Tests/examples/single_step/nal7/nal7.6.nal +++ b/Tests/examples/single_step/nal7/nal7.6.var.nal @@ -10,9 +10,6 @@ 20 -'If John enter room_101, he should open door_101 before -''outputMustContain('< (/,enter,_,room_101)> =\> (&/, (/,open,_,door_101)>,+6)>. :!6: %1.00;0.45%') - 'new: variable introduction also in time: 'If someone enter room_101, he should open door_101 before diff --git a/Tests/examples/single_step/nal7/nal7.concurrentEqual.res.nal b/Tests/examples/single_step/nal7/nal7.concurrentEqual.res.nal index bbac4cd..b7c89d3 100644 --- a/Tests/examples/single_step/nal7/nal7.concurrentEqual.res.nal +++ b/Tests/examples/single_step/nal7/nal7.concurrentEqual.res.nal @@ -3,4 +3,6 @@ B>. C>. +5 + ''outputMustContain(' C>. %1.00;0.81%') diff --git a/Tests/examples/single_step/nal7/nal7.concurrentImpl.abd.nal b/Tests/examples/single_step/nal7/nal7.concurrentImpl.abd.nal index d3b7078..9bc3727 100644 --- a/Tests/examples/single_step/nal7/nal7.concurrentImpl.abd.nal +++ b/Tests/examples/single_step/nal7/nal7.concurrentImpl.abd.nal @@ -1,6 +1,8 @@ -' (A =|> B), (A =|> C) |- (B =|> C) (Truth:Abduction) +' (A =|> B), (C =|> B) |- (A =|> C) (Truth:Induction) B>. - C>. + B>. -''outputMustContain(' C>. %1.00;0.45%') +5 + +''outputMustContain(' C>. %1.00;0.45%') diff --git a/Tests/examples/single_step/nal7/nal7.concurrentImpl.ded.nal b/Tests/examples/single_step/nal7/nal7.concurrentImpl.ded.nal index f824f98..d92163a 100644 --- a/Tests/examples/single_step/nal7/nal7.concurrentImpl.ded.nal +++ b/Tests/examples/single_step/nal7/nal7.concurrentImpl.ded.nal @@ -3,4 +3,6 @@ B>. C>. +5 + ''outputMustContain(' C>. %1.00;0.81%') diff --git a/Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.const.nal b/Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.const.nal new file mode 100644 index 0000000..84f7c34 --- /dev/null +++ b/Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.const.nal @@ -0,0 +1,6 @@ +< [hardened]> =|> [unscrewing]>>. %1.00;0.90% + [unscrewing]>! + +15 + +''outputMustContain(' [hardened]>! %1.00;0.81%') diff --git a/Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.nal b/Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.var.nal similarity index 97% rename from Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.nal rename to Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.var.nal index e182775..37fca95 100644 --- a/Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.nal +++ b/Tests/examples/single_step/nal7/nal7.concurrentImpl.goal.var.nal @@ -1,6 +1,6 @@ <<$1 --> [hardened]> =|> <$1 --> [unscrewing]>>. %1.00;0.90% <#1 --> [unscrewing]>! -10 +15 ''outputMustContain('<#1 --> [hardened]>! %1.00;0.81%') diff --git a/Tests/examples/single_step/nal7/nal7.concurrentImpl.ind.nal b/Tests/examples/single_step/nal7/nal7.concurrentImpl.ind.nal index 6ae95d3..f45ce9f 100644 --- a/Tests/examples/single_step/nal7/nal7.concurrentImpl.ind.nal +++ b/Tests/examples/single_step/nal7/nal7.concurrentImpl.ind.nal @@ -1,6 +1,8 @@ -' (A =|> B), (C =|> B) |- (A =|> C) (Truth:Induction) +' (A =|> B), (A =|> C) |- (B =|> C) (Truth:Abduction) B>. - B>. + C>. -''outputMustContain(' C>. %1.00;0.45%') +5 + +''outputMustContain(' C>. %1.00;0.45%') diff --git a/Tests/examples/single_step/nal7/nal7.eventInduction2.nal b/Tests/examples/single_step/nal7/nal7.eventInduction2.nal index 53a41df..33d2ddc 100644 --- a/Tests/examples/single_step/nal7/nal7.eventInduction2.nal +++ b/Tests/examples/single_step/nal7/nal7.eventInduction2.nal @@ -3,7 +3,7 @@ 'John is opening door_101 now <(*,John,door_101) --> open>. :|: -6 +60 'John is entering room_101 now <(*,John,room_101) --> enter>. :|: diff --git a/Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.const.nal b/Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.const.nal new file mode 100644 index 0000000..fb7d59f --- /dev/null +++ b/Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.const.nal @@ -0,0 +1,6 @@ +< [hardened]> =/> [unscrewing]>>. %1.00;0.90% + [unscrewing]>! + +15 + +''outputMustContain(' [hardened]>! %1.00;0.81%') diff --git a/Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.nal b/Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.var.nal similarity index 97% rename from Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.nal rename to Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.var.nal index 59007a4..bb8d3ba 100644 --- a/Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.nal +++ b/Tests/examples/single_step/nal7/nal7.predictiveImpl.goal.var.nal @@ -1,6 +1,6 @@ <<$1 --> [hardened]> =/> <$1 --> [unscrewing]>>. %1.00;0.90% <#1 --> [unscrewing]>! -10 +15 ''outputMustContain('<#1 --> [hardened]>! %1.00;0.81%') diff --git a/Tests/examples/single_step/nal7/nal7.retrospectiveImpl.goal.const.nal b/Tests/examples/single_step/nal7/nal7.retrospectiveImpl.goal.const.nal new file mode 100644 index 0000000..d136fcb --- /dev/null +++ b/Tests/examples/single_step/nal7/nal7.retrospectiveImpl.goal.const.nal @@ -0,0 +1,6 @@ +< [unscrewing]> =\> [hardened]>>. %1.00;0.90% + [unscrewing]>! + +10 + +''outputMustContain(' [hardened]>! %1.00;0.45%') diff --git a/Tests/examples/single_step/nal7/nal7.retrospectiveImpl.goal.nal b/Tests/examples/single_step/nal7/nal7.retrospectiveImpl.goal.var.nal similarity index 100% rename from Tests/examples/single_step/nal7/nal7.retrospectiveImpl.goal.nal rename to Tests/examples/single_step/nal7/nal7.retrospectiveImpl.goal.var.nal diff --git a/Tests/test_NAL/test_BUG_NAL4.py b/Tests/test_NAL/test_BUG_NAL4.py index 761990e..b9a280f 100644 --- a/Tests/test_NAL/test_BUG_NAL4.py +++ b/Tests/test_NAL/test_BUG_NAL4.py @@ -1,4 +1,4 @@ -import NARS +from pynars import NARS, Narsese import unittest from pynars.NARS.DataStructures import Bag, Task, Concept, Table @@ -6,12 +6,11 @@ from pynars.Narsese import Judgement, Term, Statement, Copula, Truth from pathlib import Path -import Narsese from pynars.Narsese import Compound, Connector from pynars.NAL.MetaLevelInference.VariableSubstitution import * from pynars.Narsese import VarPrefix, Variable -from pynars.NARS.RuleMap import RuleMap_v2 -from pynars.NARS import Reasoner_3_0_4 as Reasoner +from pynars.NARS.RuleMap import RuleMap +from pynars.NARS import Reasoner as Reasoner import Tests.utils_for_test as utils_for_test from Tests.utils_for_test import * diff --git a/Tests/test_NAL/test_NAL1.py b/Tests/test_NAL/test_NAL1.py index a656bb8..c42eb04 100644 --- a/Tests/test_NAL/test_NAL1.py +++ b/Tests/test_NAL/test_NAL1.py @@ -1,4 +1,4 @@ -import NARS +from pynars import NARS, Narsese import unittest from pynars.NARS.DataStructures import Bag, Task, Concept, Table @@ -6,17 +6,16 @@ from pynars.Narsese import Judgement, Term, Statement, Copula, Truth from pathlib import Path -import Narsese from pynars.Narsese import Compound, Connector from pynars.NAL.MetaLevelInference.VariableSubstitution import * from pynars.Narsese import VarPrefix, Variable -from pynars.NARS.RuleMap import RuleMap_v2 -from pynars.NARS import Reasoner_3_0_4 as Reasoner +from pynars.NARS.RuleMap import RuleMap +from pynars.NARS import Reasoner as Reasoner import Tests.utils_for_test as utils_for_test from Tests.utils_for_test import * -utils_for_test.rule_map = RuleMap_v2() +utils_for_test.engine = RuleMap() class TEST_NAL1(unittest.TestCase): diff --git a/Tests/test_NAL/test_NAL2.py b/Tests/test_NAL/test_NAL2.py index 4af42c9..fe6d714 100644 --- a/Tests/test_NAL/test_NAL2.py +++ b/Tests/test_NAL/test_NAL2.py @@ -1,6 +1,6 @@ import unittest -import Narsese +from pynars import Narsese from pynars.NAL.MetaLevelInference.VariableSubstitution import * from Tests.utils_for_test import * diff --git a/Tests/test_NAL/test_NAL3.py b/Tests/test_NAL/test_NAL3.py index c848c0d..a2923c6 100644 --- a/Tests/test_NAL/test_NAL3.py +++ b/Tests/test_NAL/test_NAL3.py @@ -1,4 +1,4 @@ -import NARS +from pynars import NARS, Narsese import unittest from pynars.NARS.DataStructures import Bag, Task, Concept, Table @@ -6,12 +6,11 @@ from pynars.Narsese import Judgement, Term, Statement, Copula, Truth from pathlib import Path -import Narsese from pynars.Narsese import Compound, Connector from pynars.NAL.MetaLevelInference.VariableSubstitution import * from pynars.Narsese import VarPrefix, Variable -from pynars.NARS.RuleMap import RuleMap_v2 -from pynars.NARS import Reasoner_3_0_4 as Reasoner +from pynars.NARS.RuleMap import RuleMap +from pynars.NARS import Reasoner as Reasoner import Tests.utils_for_test as utils_for_test from Tests.utils_for_test import * diff --git a/Tests/test_NAL/test_NAL4.py b/Tests/test_NAL/test_NAL4.py index 78994ff..11992f5 100644 --- a/Tests/test_NAL/test_NAL4.py +++ b/Tests/test_NAL/test_NAL4.py @@ -1,4 +1,4 @@ -import NARS +from pynars import NARS, Narsese import unittest from pynars.NARS.DataStructures import Bag, Task, Concept, Table @@ -6,12 +6,11 @@ from pynars.Narsese import Judgement, Term, Statement, Copula, Truth from pathlib import Path -import Narsese from pynars.Narsese import Compound, Connector from pynars.NAL.MetaLevelInference.VariableSubstitution import * from pynars.Narsese import VarPrefix, Variable -from pynars.NARS.RuleMap import RuleMap_v2 -from pynars.NARS import Reasoner_3_0_4 as Reasoner +from pynars.NARS.RuleMap import RuleMap +from pynars.NARS import Reasoner as Reasoner import Tests.utils_for_test as utils_for_test from Tests.utils_for_test import * diff --git a/Tests/test_NAL/test_NAL5.py b/Tests/test_NAL/test_NAL5.py index 950d2b0..671c7d8 100644 --- a/Tests/test_NAL/test_NAL5.py +++ b/Tests/test_NAL/test_NAL5.py @@ -4,14 +4,13 @@ import unittest from pathlib import Path -import NARS -import Narsese +from pynars import NARS, Narsese import Tests.utils_for_test as utils_for_test from pynars.NAL.MetaLevelInference.VariableSubstitution import * -from pynars.NARS import Reasoner_3_0_4 as Reasoner +from pynars.NARS import Reasoner as Reasoner from pynars.NARS.DataStructures import Bag, Concept, Table, Task from pynars.NARS.DataStructures._py.Link import TaskLink, TermLink -from pynars.NARS.RuleMap import RuleMap_v2 +from pynars.NARS.RuleMap import RuleMap from pynars.Narsese import (Compound, Connector, Copula, Judgement, Statement, Term, Truth, Variable, VarPrefix) from Tests.utils_for_test import * diff --git a/Tests/test_NAL/test_NAL6.py b/Tests/test_NAL/test_NAL6.py index 2ceeee5..51d9b96 100644 --- a/Tests/test_NAL/test_NAL6.py +++ b/Tests/test_NAL/test_NAL6.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import Task from pynars.NAL.MetaLevelInference.VariableSubstitution import * -from pynars.NARS.RuleMap import RuleMap_v2 +from pynars.NARS.RuleMap import RuleMap import Tests.utils_for_test as utils_for_test from Tests.utils_for_test import * diff --git a/Tests/test_NAL/test_NAL7.py b/Tests/test_NAL/test_NAL7.py index 26bcaef..1ace125 100644 --- a/Tests/test_NAL/test_NAL7.py +++ b/Tests/test_NAL/test_NAL7.py @@ -2,7 +2,7 @@ from pynars.NAL.MetaLevelInference.VariableSubstitution import * from pynars.NARS.InferenceEngine import GeneralEngine -from pynars.NARS.RuleMap import RuleMap_v2 +from pynars.NARS.RuleMap import RuleMap import Tests.utils_for_test as utils_for_test from Tests.utils_for_test import * @@ -629,6 +629,346 @@ def test_deduction_sequence(self): ) pass +class TEST_NAL7_ANALOGY(unittest.TestCase): + def test_analogy_0_0__0(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'A.' + ) + if rules is not None: + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertFalse( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_0_0__1(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_0_0__2(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_0_0__3(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_0_0__4(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_0_0__5(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_0_1__0(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'A>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_0_1__1(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'A>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_0_1__2(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'A>. %1.00;0.90%', + 'A.' + ) + if rules is not None: + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertFalse( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_0_1__3(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'A>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_0_1__4(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'A>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_0_1__5(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'A>. %1.00;0.90%', + 'A.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'B>. %1.00;0.81%') + ) + + def test_analogy_1_0__0(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_1_0__1(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_1_0__2(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'B.' + ) + if rules is not None: + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertFalse( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_1_0__3(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'A>. %1.00;0.81%') + ) + + def test_analogy_1_0__4(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_1_0__5(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'C>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_1_1__0(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'B>. %1.00;0.90%', + 'B.' + ) + if rules is not None: + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_1_1__1(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'B>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_1_1__2(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'B>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'A>. %1.00;0.81%') + ) + + def test_analogy_1_1__3(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'B>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'A>. %1.00;0.81%') + ) + + def test_analogy_1_1__4(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'B>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) + + def test_analogy_1_1__5(self): + ''' + + ''' + rules, task, belief, concept, task_link, term_link, result1, result2 = rule_map_two_premises( + 'B>. %1.00;0.90%', + 'B>. %1.00;0.90%', + 'B.' + ) + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] + self.assertTrue( + output_contains(tasks_derived, 'C>. %1.00;0.81%') + ) if __name__ == '__main__': diff --git a/Tests/test_NAL/test_NAL8.py b/Tests/test_NAL/test_NAL8.py index 8ed197c..2c92b09 100644 --- a/Tests/test_NAL/test_NAL8.py +++ b/Tests/test_NAL/test_NAL8.py @@ -1,12 +1,12 @@ import unittest from pynars.NAL.MetaLevelInference.VariableSubstitution import * -from pynars.NARS.RuleMap import RuleMap_v2 +from pynars.NARS.RuleMap import RuleMap import Tests.utils_for_test as utils_for_test from Tests.utils_for_test import * -utils_for_test.rule_map = RuleMap_v2() +utils_for_test.engine = RuleMap() class TEST_NAL8(unittest.TestCase): diff --git a/Tests/test_NAL/test_NAL9.py b/Tests/test_NAL/test_NAL9.py index 393e07e..014d5ad 100644 --- a/Tests/test_NAL/test_NAL9.py +++ b/Tests/test_NAL/test_NAL9.py @@ -1,7 +1,7 @@ import unittest from pynars.NAL.MetaLevelInference.VariableSubstitution import * -from pynars.NARS.RuleMap import RuleMap_v2 +from pynars.NARS.RuleMap import RuleMap import Tests.utils_for_test as utils_for_test from Tests.utils_for_test import * diff --git a/Tests/test_RuleMap/_trash/test_RuleLUT.py b/Tests/test_RuleMap/_trash/test_RuleLUT.py index 5d54bd1..8283b48 100644 --- a/Tests/test_RuleMap/_trash/test_RuleLUT.py +++ b/Tests/test_RuleMap/_trash/test_RuleLUT.py @@ -1,7 +1,7 @@ from pynars.utils.RuleLUT import RuleLUT, Any from pynars.NARS.DataStructures._py.Link import LinkType -from pynars.NARS.RuleMap import Interface_SyllogisticRules, RuleMap_v2 +from pynars.NARS.RuleMap import Interface_SyllogisticRules, RuleMap from pynars.Narsese import Budget import unittest @@ -10,7 +10,7 @@ from pynars.utils.SparseLUT import SparseLUT -from pynars.NARS.RuleMap.RuleMap_v2 import CommonId +from pynars.NARS.RuleMap.RuleMap import CommonId class TEST_RuleLUT(unittest.TestCase): diff --git a/Tests/test_RuleMap/test_RuleMap_v2.py b/Tests/test_RuleMap/test_RuleMap_v2.py index 74e2e8b..2abe409 100644 --- a/Tests/test_RuleMap/test_RuleMap_v2.py +++ b/Tests/test_RuleMap/test_RuleMap_v2.py @@ -3,11 +3,11 @@ from pynars.NARS.DataStructures import Bag, Task from pynars.Narsese import Judgement, Term, Statement, Copula, Truth -import Narsese +from pynars import Narsese from pynars.NARS.DataStructures import Concept from pynars.Narsese import Copula -from pynars.NARS.RuleMap import RuleMap_v2 -from pynars.NARS.RuleMap.RuleMap_v2 import CommonId +from pynars.NARS.RuleMap import RuleMap +from pynars.NARS.RuleMap.RuleMap import CommonId from pynars.NARS.DataStructures import LinkType class TEST_RuleMap_v2(unittest.TestCase): @@ -15,7 +15,7 @@ def __init__(self, methodName: str = ...) -> None: super().__init__(methodName=methodName) def test_0(self): - rulemap = RuleMap_v2(False) + rulemap = RuleMap(False) rulemap.build(False) rulemap.draw(show_labels=False) pass diff --git a/Tests/test_RuleMap/test_sparse_lut.py b/Tests/test_RuleMap/test_sparse_lut.py index 3b7fcd7..d247b49 100644 --- a/Tests/test_RuleMap/test_sparse_lut.py +++ b/Tests/test_RuleMap/test_sparse_lut.py @@ -1,6 +1,6 @@ from networkx.generators.random_graphs import fast_gnp_random_graph from pynars.NARS.DataStructures._py.Link import LinkType -from pynars.NARS.RuleMap import Interface_SyllogisticRules, RuleMap_v2 +from pynars.NARS.RuleMap import Interface_SyllogisticRules, RuleMap from pynars.Narsese import Budget import unittest @@ -9,8 +9,8 @@ from pynars.utils.SparseLUT import SparseLUT, Any from pynars.utils.tools import get_size -from pynars.NARS.RuleMap.RuleMap_v2 import CommonId -from pynars.utils.SparseLUT.sparse_lut_v3.branch_list import Node +from pynars.NARS.RuleMap.RuleMap import CommonId +from pynars.utils.SparseLUT.branch_list import Node class TEST_SparseLUT(unittest.TestCase): diff --git a/Tests/test_extract_feature.py b/Tests/test_extract_feature.py index 88d59d3..42e7317 100644 --- a/Tests/test_extract_feature.py +++ b/Tests/test_extract_feature.py @@ -1,14 +1,14 @@ -import NARS +from pynars import NARS import unittest from pynars.NARS.DataStructures import Bag, Task, Concept, Table from pynars.Narsese import Judgement, Term, Statement, Copula, Truth from pathlib import Path -import Narsese +from pynars import Narsese from pynars.Narsese import Compound, Connector -from pynars.NARS.RuleMap.RuleMap_v2 import extract_feature +from pynars.NARS.RuleMap.RuleMap import extract_feature class TEST_ExtractFeature(unittest.TestCase): diff --git a/Tests/utils_for_test.py b/Tests/utils_for_test.py index 2d9c287..01b8430 100644 --- a/Tests/utils_for_test.py +++ b/Tests/utils_for_test.py @@ -1,17 +1,19 @@ from typing import List, Tuple +from pynars.NAL import Inference from pynars.NARS.DataStructures._py.Concept import Concept from pynars.NARS.DataStructures._py.Link import Link, TaskLink, TermLink +from pynars.NARS.InferenceEngine.GeneralEngine.GeneralEngine import GeneralEngine from pynars.Narsese import Task -import Narsese -from pynars.NARS.RuleMap import RuleMap_v2, RuleCallable -from pynars.NARS import Reasoner_3_0_4 as Reasoner +from pynars import Narsese +from pynars.NARS.RuleMap import RuleMap, RuleCallable +from pynars.NARS import Reasoner as Reasoner from pynars.Narsese._py.Statement import Statement from pynars.Narsese._py.Task import Belief from pynars.Narsese._py.Term import Term from pynars.NAL.MentalOperation import execute nars = Reasoner(100, 100) -rule_map = nars.inference.rule_map +engine: GeneralEngine = nars.inference def rule_map_two_premises(premise1: str, premise2: str, term_common: str, inverse: bool=False, is_belief_term: bool=False, index_task=None, index_belief=None) -> Tuple[List[RuleCallable], Task, Belief, Concept, TaskLink, TermLink, Tuple[Task, Task, Task, Task]]: @@ -47,7 +49,7 @@ def rule_map_two_premises(premise1: str, premise2: str, term_common: str, invers term_link = concept.term_links.take_by_key(TermLink(concept, belief, None, index=index_belief)) belief: Belief - rules = rule_map.match(task, (belief if not is_belief_term else None), belief.term, task_link, term_link) + _, _, rules = engine.match(task, (belief if not is_belief_term else None), belief.term, task_link, term_link) return rules, task, belief, concept, task_link, term_link, result1, result2 def rule_map_task_only(premise1: str, conecept_term: str, index_concept_task: tuple): @@ -59,7 +61,7 @@ def rule_map_task_only(premise1: str, conecept_term: str, index_concept_task: tu concept = nars.memory.take_by_key(concept_term) task_link = concept.task_links.take_by_key(TaskLink(concept, task, None, index=index_concept_task)) - rules = rule_map.match(task, None, None, task_link, None) + rules = engine.match(task, None, None, task_link, None) return rules, task, concept, task_link, result1 diff --git a/pynars/Config.py b/pynars/Config.py index a5f7bab..e441b6a 100644 --- a/pynars/Config.py +++ b/pynars/Config.py @@ -102,7 +102,7 @@ def load(file_path: str): valid = False if not valid: file_path = Path(__file__).parent/'config.json' - print(f'config file: {file_path}') + print(f'Loaded config file: {file_path}') try: with open(file_path, 'r') as f: content = json.load(f) diff --git a/pynars/Console.py b/pynars/Console.py index 601d5aa..b6acfdc 100644 --- a/pynars/Console.py +++ b/pynars/Console.py @@ -8,7 +8,7 @@ from pynars.Narsese.Parser.parser import TreeToNarsese from pynars.Narsese import Sentence import random -from pynars.NARS import Reasoner_3_0_4 as Reasoner +from pynars.NARS import Reasoner as Reasoner from pynars.utils.Print import out_print, PrintType from pynars.Narsese import Task from typing import List diff --git a/pynars/NAL/Functions/StampFunctions.py b/pynars/NAL/Functions/StampFunctions.py index 4bdf64c..00c1262 100644 --- a/pynars/NAL/Functions/StampFunctions.py +++ b/pynars/NAL/Functions/StampFunctions.py @@ -14,6 +14,7 @@ def Stamp_merge(stamp1: Stamp, stamp2: Stamp, order_mark: Union[Copula, Connector]=None, reverse_order=False, t_bias=0): stamp: Stamp = deepcopy(stamp1) + # stamp.is_external = stamp1.is_external if stamp is not None: stamp.extend_evidenital_base(stamp2.evidential_base) if not stamp1.is_eternal and not stamp2.is_eternal: diff --git a/pynars/NAL/Inference/SyllogisticRules.py b/pynars/NAL/Inference/SyllogisticRules.py index 22babc5..f3e4984 100644 --- a/pynars/NAL/Inference/SyllogisticRules.py +++ b/pynars/NAL/Inference/SyllogisticRules.py @@ -461,7 +461,7 @@ def comparison(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_ stat2: Statement = premise2.term stamp = Stamp_merge(stamp_task, stamp_belief) - copula = stat1.copula.symmetrize if not inverse_copula else stat2.copula.symmetrize + copula = stat1.copula.symmetrize() if not inverse_copula else stat2.copula.symmetrize() statement = Statement(stat2.predicate, copula, stat1.predicate) if not inverse_copula else Statement(stat2.subject, copula, stat1.subject) if punct_task.is_judgement: @@ -539,7 +539,7 @@ def reversion(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_t stamp = Stamp_merge(stamp_task, stamp_belief) if task.is_judgement: - statement = Statement(stat2.subject, stat1.copula.symmetrize, stat1.subject) + statement = Statement(stat2.subject, stat1.copula.symmetrize(), stat1.subject) truth = Truth_intersection(premise1.truth, premise2.truth) budget = Budget_forward(truth, budget_tasklink, budget_termlink) sentence_derived = Judgement(statement, stamp, truth) diff --git a/pynars/NAL/Inference/TemporalRules.py b/pynars/NAL/Inference/TemporalRules.py index a46c057..0bad962 100644 --- a/pynars/NAL/Inference/TemporalRules.py +++ b/pynars/NAL/Inference/TemporalRules.py @@ -1,9 +1,11 @@ +from typing import Dict, Tuple from pynars.Narsese import Task, Belief, Sentence, Judgement, Goal, Question, Quest from pynars.Narsese import Statement, Term, Compound from pynars.Narsese import Budget, Stamp from pynars.Narsese import truth_analytic from pynars.Config import Enable from pynars.Narsese._py.Interval import Interval +from pynars.Narsese._py.Terms import Terms from ..Functions import * from copy import copy, deepcopy @@ -69,6 +71,56 @@ def deduction_sequence_eliminate(task: Task, belief: Belief, budget_tasklink: Bu return Task(sentence_derived, budget) +def deduction_sequence_replace(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): + ''' + + premise1: <(&/, C, ..., +100) =/> P>. + premise2: (&/, S, ..., +100)=/>C. :|: + |- + conclusion: <(&/, S, ..., +100, ..., +100)=/>P>. + ''' + premise1, premise2 = (task.sentence, belief.sentence) if not inverse_premise else (belief.sentence, task.sentence) + + stamp_task: Stamp = task.stamp + stamp_belief: Stamp = belief.stamp + + stat1: Statement = premise1.term + stat2: Statement = premise2.term + + compound1: Compound = stat1.subject + compound1 = compound1 - stat2.predicate + interval1: Interval = compound1.terms[0] + compound2: Compound = stat2.subject + interval2: Interval = compound2.terms[-1] + if interval1.is_interval and interval2.is_interval: + interval = interval1 + interval2 + compound = Compound(compound2.connector, *compound2.terms[:-1], interval) + else: + compound = Compound(compound2.connector, *compound2.terms, *compound1.terms) + + statement = Statement(compound, stat1.copula, stat1.predicate) + + stamp = Stamp_merge(stamp_task, stamp_belief) + if task.is_judgement: + truth = Truth_deduction(premise1.truth, premise2.truth) + budget = Budget_forward(truth, budget_tasklink, budget_termlink) + sentence_derived = Judgement(statement, stamp, truth) + elif task.is_goal: + truth = Desire_induction(task.truth, belief.truth) + budget = Budget_forward(truth, budget_tasklink, budget_termlink) + sentence_derived = Goal(statement, stamp, truth) + elif task.is_question: + curiosity = None # TODO + budget = Budget_backward_weak(belief.truth, budget_tasklink, budget_termlink) + sentence_derived = Question(statement, stamp, curiosity) + elif task.is_quest: + curiosity = None # TODO + budget = Budget_backward_weak(belief.truth, budget_tasklink, budget_termlink) + sentence_derived = Quest(statement, stamp, curiosity) + else: raise "Invalid case." + + return Task(sentence_derived, budget) + def abduction(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): ''' Testcase: nal7.18.nal @@ -125,6 +177,90 @@ def abduction(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_t return Task(sentence_derived, budget) +def analogy(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): + ''' + premise1: P> (inverse:

M>) + premise2: M> (inverse: M>) + |- + conclusion: P> (inverse:

S>) + + premise1: P> (inverse:

M>) + premise2: S> (inverse: S>) + |- + conclusion: P> (inverse:

S>) + ''' + premise1, premise2 = (task.sentence, belief.sentence) if not inverse_premise else (belief.sentence, task.sentence) + + stamp_task: Stamp = task.stamp + stamp_belief: Stamp = belief.stamp + truth_belief: Truth = belief.truth + + stat1: Statement = premise1.term + stat2: Statement = premise2.term + stat1_subject = stat1.subject + stat1_predicate = stat1.predicate + + copula_dict: Dict[Tuple[Copula, Copula], Copula]= analogy.copula_dict + copula1 = stat1.copula + copula2 = stat2.copula + if copula1 is Copula.RetrospectiveImplication: + copula1 = copula1.PredictiveImplication + inverse_copula = not inverse_copula + stat1_subject, stat1_predicate = stat1_predicate, stat1_subject + + copula = copula_dict[(copula1, copula2)] + + stamp = Stamp_merge(stamp_task, stamp_belief) + + # TODO + if not inverse_copula: + if stat2.predicate == stat1_subject: + statement = Statement(stat2.subject, copula, stat1_predicate) + elif stat2.subject == stat1_subject: + if copula1 is Copula.ConcurrentImplication and copula2 is Copula.PredictiveEquivalence: + # {A=|>B>. C>.} |- C>. + copula = copula.inverse() + statement = Statement(stat2.predicate, copula, stat1_predicate) + else: raise "Invalid case." + else: + if stat2.predicate == stat1_predicate: + if copula1 is Copula.ConcurrentImplication and copula2 is Copula.PredictiveEquivalence: + # {A=|>B>. B>.} |- C>. + copula = copula.inverse() + statement = Statement(stat1_subject, copula, stat2.subject) + elif stat2.subject == stat1_predicate: + statement = Statement(stat1_subject, copula, stat2.predicate) + else: raise "Invalid case." + + + if task.is_judgement: + truth = Truth_analogy(premise1.truth, premise2.truth) + budget = Budget_forward(truth, budget_tasklink, budget_termlink) + sentence_derived = Judgement(statement, stamp, truth) + elif task.is_goal: + Desire_function = Desire_weak if task.term.is_commutative else Desire_strong + truth = Desire_function(premise1.truth, premise2.truth) + budget = Budget_forward(truth, budget_tasklink, budget_termlink) + sentence_derived = Goal(statement, stamp, truth) + elif task.is_question: + curiosity = None # TODO + budget = Budget_backward_weak(truth_belief, budget_tasklink, budget_termlink) + sentence_derived = Question(statement, stamp, curiosity) + elif task.is_quest: + curiosity = None # TODO + budget = Budget_backward(truth_belief, budget_tasklink, budget_termlink) + sentence_derived = Quest(statement, stamp, curiosity) + else: raise "Invalid case." + + return Task(sentence_derived, budget) + +analogy.copula_dict = { + (Copula.PredictiveImplication, Copula.PredictiveEquivalence): Copula.PredictiveImplication, + (Copula.ConcurrentImplication, Copula.PredictiveEquivalence): Copula.PredictiveImplication, + (Copula.PredictiveImplication, Copula.ConcurrentEquivalence): Copula.PredictiveImplication, + (Copula.ConcurrentImplication, Copula.ConcurrentEquivalence): Copula.ConcurrentImplication, +} + def sequence(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): ''' (&/, A, B, C)! @@ -230,6 +366,14 @@ def immediate_goal_deriviation(task: Task, belief: Belief, budget_tasklink: Budg '''Temporal Induction Rules''' +''' +{A. :\:; B. :|:} |- B>. :|: +{A. :\:; B. :|:} |- (&/, A, +5, B). :|: +{A. :\:; C>. :|:} |- <(&/, A, +5, B)=/>C>. :|: +''' + +# TODO: each rule-function should be renamed. + def induction_implication(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): ''' judgements of both of task and belief should be events. @@ -276,15 +420,171 @@ def induction_implication(task: Task, belief: Belief, budget_tasklink: Budget=No return Task(sentence_derived, budget) +def induction_equivalence(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): + ''' + judgements of both of task and belief should be events. + + premise1: A. :\: + premise2: B. :|: + conclusion: B>. :|: + + + Reference: + [1] OpenNARS 3.0.4 TemporalRules.java line 147~263 temporalInduction(...) + + Testcase: nal7.6.nal + ''' + premise1, premise2 = (task.sentence, belief.sentence) if not inverse_premise else (belief.sentence, task.sentence) + + stamp_task: Stamp = task.stamp + stamp_belief: Stamp = belief.stamp + + stat1: Statement = premise1.term + stat2: Statement = premise2.term + + time_diff = premise2.stamp.t_occurrence - premise1.stamp.t_occurrence + interval = Interval(abs(time_diff)) + if abs(time_diff) < Config.temporal_duration: + # concurrent + statement = Statement(stat1, Copula.ConcurrentEquivalence, stat2) + stamp = Stamp_merge(stamp_task, stamp_belief) + elif time_diff > 0: + # predictive + statement = Statement(Compound.SequentialEvents(stat1, interval), Copula.PredictiveEquivalence, stat2) + stamp = Stamp_merge(premise2.stamp, premise1.stamp) + else: # time_diff < 0 + # retrospective + statement = Statement(Compound.SequentialEvents(stat2, interval), Copula.PredictiveEquivalence, stat1) + stamp = Stamp_merge(premise1.stamp, premise2.stamp) + + if task.is_judgement: + truth = Truth_induction(premise1.truth, premise2.truth) + budget = Budget_forward(truth, budget_tasklink if budget_tasklink is not None else task.budget, budget_termlink) + sentence_derived = Judgement(statement, stamp, truth) + else: raise "Invalid case." + + return Task(sentence_derived, budget) + + + def induction_composition(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): ''' judgements of both of task and belief should be events. + premise1: A. :\: + premise2: B. :|: + conclusion: (&/, A, +5, B). :|: + + + Reference: + [1] OpenNARS 3.0.4 TemporalRules.java line 147~263 temporalInduction(...) + + Testcase: nal7.6.nal + ''' + premise1, premise2 = (task.sentence, belief.sentence) if not inverse_premise else (belief.sentence, task.sentence) + + stamp_task: Stamp = task.stamp + stamp_belief: Stamp = belief.stamp + + stat1: Statement = premise1.term + stat2: Statement = premise2.term + + time_diff = premise2.stamp.t_occurrence - premise1.stamp.t_occurrence + interval = Interval(abs(time_diff)) + if abs(time_diff) < Config.temporal_duration: + # parallel + statement = Compound.ParallelEvents(stat1, stat2) + stamp = Stamp_merge(stamp_task, stamp_belief) + elif time_diff > 0: + # sequential + statement = Compound.SequentialEvents(stat1, interval, stat2) + stamp = Stamp_merge(premise2.stamp, premise1.stamp) + else: # time_diff < 0 + # sequential + statement = Compound.SequentialEvents(stat2, interval, stat1) + stamp = Stamp_merge(premise1.stamp, premise2.stamp) + + if task.is_judgement: + truth = Truth_induction(premise1.truth, premise2.truth) + budget = Budget_forward(truth, budget_tasklink if budget_tasklink is not None else task.budget, budget_termlink) + sentence_derived = Judgement(statement, stamp, truth) + else: raise "Invalid case." + + return Task(sentence_derived, budget) + + + +def induction_predictive_implication_composition(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): + ''' + judgements of both of task and belief should be events. + premise1: A. :\: premise2: C>. :|: conclusion: <(&/, A, +5, B)=/>C>. :|: + Reference: + [1] OpenNARS 3.0.4 TemporalRules.java line 147~263 temporalInduction(...) + + Testcase: nal7.7.nal + ''' + premise1, premise2 = (task.sentence, belief.sentence) if not inverse_premise else (belief.sentence, task.sentence) + + stamp_task: Stamp = task.stamp + stamp_belief: Stamp = belief.stamp + + stat1: Statement = premise1.term + stat2: Statement = premise2.term + + # stat2_subject, stat2_predicate, stat2_copula = (stat2.subject, stat2.predicate, stat2.copula) if not inverse_copula else (stat2.predicate, stat2.subject, stat2.copula.inverse()) + + time_diff = premise2.stamp.t_occurrence - premise1.stamp.t_occurrence + interval = Interval(abs(time_diff)) + if abs(time_diff) < Config.temporal_duration: + # concurrent + # TODO: I doubt this rule below. So I modified it into a new one, but it should be further justified. + # # subject = Compound.ParallelEvents(stat1, stat2.subject) + # # copula = Copula.ConcurrentImplication # stat2.copula + # # predicate = stat2.predicate + + subject = stat2.subject + copula = stat2.copula + predicate = Compound.ParallelEvents(stat1, stat2.predicate) + stamp = Stamp_merge(stamp_task, stamp_belief) + elif time_diff > 0: + # predictive + subject = Compound.SequentialEvents(stat1, interval, stat2.subject) + copula = stat2.copula + predicate = stat2.predicate + stamp = Stamp_merge(premise2.stamp, premise1.stamp) + else: # time_diff < 0 + # retrospective + subject = stat2.subject + copula = stat2.copula + predicate = Compound.SequentialEvents(stat2.predicate, interval, stat1) + stamp = Stamp_merge(premise1.stamp, premise2.stamp) + if inverse_copula: + subject, copula, predicate = predicate, copula.inverse(), subject + statement = Statement(subject, copula, predicate) + + if task.is_judgement: + truth = Truth_induction(premise1.truth, premise2.truth) + budget = Budget_forward(truth, budget_tasklink if budget_tasklink is not None else task.budget, budget_termlink) + sentence_derived = Judgement(statement, stamp, truth) + else: raise "Invalid case." + + return Task(sentence_derived, budget) + + +def induction_retrospective_implication_composition(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): + ''' + judgements of both of task and belief should be events. + + premise1: A. :\: + premise2: C>. :|: + conclusion: <(&/, A, +5, C)=/>B>. :|: + + Reference: [1] OpenNARS 3.0.4 TemporalRules.java line 147~263 temporalInduction(...) @@ -302,16 +602,30 @@ def induction_composition(task: Task, belief: Belief, budget_tasklink: Budget=No interval = Interval(abs(time_diff)) if abs(time_diff) < Config.temporal_duration: # concurrent - statement = Statement(Compound.ParallelEvents(stat1, stat2.subject), Copula.ConcurrentImplication, stat2.predicate) + # TODO: I doubt this rule below. So I modified it into a new one, but it should be further justified. + # # subject = Compound.ParallelEvents(stat1, stat2.subject) + # # copula = Copula.ConcurrentImplication # stat2.copula + # # predicate = stat2.predicate + + subject = stat2.predicate + copula = stat2.copula.inverse() + predicate = Compound.ParallelEvents(stat1, stat2.subject) stamp = Stamp_merge(stamp_task, stamp_belief) elif time_diff > 0: # predictive - statement = Statement(Compound.SequentialEvents(stat1, interval, stat2.subject), Copula.PredictiveImplication, stat2.predicate) + subject = Compound.SequentialEvents(stat1, interval, stat2.predicate) + copula = stat2.copula.inverse() + predicate = stat2.subject stamp = Stamp_merge(premise2.stamp, premise1.stamp) else: # time_diff < 0 # retrospective - statement = Statement(stat2.subject, Copula.RetrospectiveImplication, Compound.SequentialEvents(stat2.predicate, interval, stat1)) + subject = stat2.predicate + copula = stat2.copula.inverse() + predicate = Compound.SequentialEvents(stat2.subject, interval, stat1) stamp = Stamp_merge(premise1.stamp, premise2.stamp) + if inverse_copula: + subject, copula, predicate = predicate, copula.inverse(), subject + statement = Statement(subject, copula, predicate) if task.is_judgement: truth = Truth_induction(premise1.truth, premise2.truth) @@ -320,3 +634,125 @@ def induction_composition(task: Task, belief: Belief, budget_tasklink: Budget=No else: raise "Invalid case." return Task(sentence_derived, budget) + + +def induction_predictive_equivalance_composition(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): + ''' + judgements of both of task and belief should be events. + + premise1: A. :\: + premise2: C>. :|: + conclusion: <(&/, A, +5, B)C>. :|: + + + Reference: + [1] OpenNARS 3.0.4 TemporalRules.java line 147~263 temporalInduction(...) + + Testcase: nal7.7.nal + ''' + premise1, premise2 = (task.sentence, belief.sentence) if not inverse_premise else (belief.sentence, task.sentence) + + stamp_task: Stamp = task.stamp + stamp_belief: Stamp = belief.stamp + + stat1: Statement = premise1.term + stat2: Statement = premise2.term + + # stat2_subject, stat2_predicate, stat2_copula = (stat2.subject, stat2.predicate, stat2.copula) if not inverse_copula else (stat2.predicate, stat2.subject, stat2.copula.inverse()) + + time_diff = premise2.stamp.t_occurrence - premise1.stamp.t_occurrence + interval = Interval(abs(time_diff)) + if abs(time_diff) < Config.temporal_duration: + # concurrent + # TODO: I doubt this rule below. So I modified it into a new one, but it should be further justified. + # # subject = Compound.ParallelEvents(stat1, stat2.subject) + # # copula = Copula.ConcurrentImplication # stat2.copula + # # predicate = stat2.predicate + + subject = stat2.subject + copula = Copula.PredictiveEquivalence + predicate = Compound.ParallelEvents(stat1, stat2.predicate) + stamp = Stamp_merge(stamp_task, stamp_belief) + elif time_diff > 0: + # predictive + subject = Compound.SequentialEvents(stat1, interval, stat2.subject) + copula = Copula.PredictiveEquivalence + predicate = stat2.predicate + stamp = Stamp_merge(premise2.stamp, premise1.stamp) + else: # time_diff < 0 + # retrospective + subject = stat2.subject + copula = Copula.PredictiveEquivalence + predicate = Compound.SequentialEvents(stat2.predicate, interval, stat1) + stamp = Stamp_merge(premise1.stamp, premise2.stamp) + if inverse_copula: + subject, copula, predicate = predicate, copula.inverse(), subject + statement = Statement(subject, copula, predicate) + + if task.is_judgement: + truth = Truth_induction(premise1.truth, premise2.truth) + budget = Budget_forward(truth, budget_tasklink if budget_tasklink is not None else task.budget, budget_termlink) + sentence_derived = Judgement(statement, stamp, truth) + else: raise "Invalid case." + + return Task(sentence_derived, budget) + + +def induction_retrospective_equivalance_composition(task: Task, belief: Belief, budget_tasklink: Budget=None, budget_termlink: Budget=None, inverse_premise: bool=False, inverse_copula: bool=False): + ''' + judgements of both of task and belief should be events. + + premise1: A. :\: + premise2: C>. :|: + conclusion: <(&/, A, +5, C)B>. :|: + + + Reference: + [1] OpenNARS 3.0.4 TemporalRules.java line 147~263 temporalInduction(...) + + Testcase: nal7.7.nal + ''' + premise1, premise2 = (task.sentence, belief.sentence) if not inverse_premise else (belief.sentence, task.sentence) + + stamp_task: Stamp = task.stamp + stamp_belief: Stamp = belief.stamp + + stat1: Statement = premise1.term + stat2: Statement = premise2.term + + time_diff = premise2.stamp.t_occurrence - premise1.stamp.t_occurrence + interval = Interval(abs(time_diff)) + if abs(time_diff) < Config.temporal_duration: + # concurrent + # TODO: I doubt this rule below. So I modified it into a new one, but it should be further justified. + # # subject = Compound.ParallelEvents(stat1, stat2.subject) + # # copula = Copula.ConcurrentImplication # stat2.copula + # # predicate = stat2.predicate + + subject = stat2.predicate + copula = Copula.PredictiveEquivalence + predicate = Compound.ParallelEvents(stat1, stat2.subject) + stamp = Stamp_merge(stamp_task, stamp_belief) + elif time_diff > 0: + # predictive + subject = Compound.SequentialEvents(stat1, interval, stat2.predicate) + copula = Copula.PredictiveEquivalence + predicate = stat2.subject + stamp = Stamp_merge(premise2.stamp, premise1.stamp) + else: # time_diff < 0 + # retrospective + subject = stat2.predicate + copula = Copula.PredictiveEquivalence + predicate = Compound.SequentialEvents(stat2.subject, interval, stat1) + stamp = Stamp_merge(premise1.stamp, premise2.stamp) + if inverse_copula: + subject, copula, predicate = predicate, copula.inverse(), subject + statement = Statement(subject, copula, predicate) + + if task.is_judgement: + truth = Truth_induction(premise1.truth, premise2.truth) + budget = Budget_forward(truth, budget_tasklink if budget_tasklink is not None else task.budget, budget_termlink) + sentence_derived = Judgement(statement, stamp, truth) + else: raise "Invalid case." + + return Task(sentence_derived, budget) \ No newline at end of file diff --git a/pynars/NAL/Inference/__init__.py b/pynars/NAL/Inference/__init__.py index 921feb1..84bb719 100644 --- a/pynars/NAL/Inference/__init__.py +++ b/pynars/NAL/Inference/__init__.py @@ -54,10 +54,17 @@ from .TemporalRules import \ abduction as temporal__abduction, \ + analogy as temporal__analogy, \ deduction_sequence_eliminate as temporal__deduction_sequence_eliminate, \ + deduction_sequence_replace as temporal__deduction_sequence_replace, \ immediate_goal_deriviation as temporal__immediate_goal_deriviation, \ induction_composition as temporal__induction_composition, \ + induction_equivalence as temporal__induction_equivalence, \ induction_implication as temporal__induction_implication, \ + induction_predictive_equivalance_composition as temporal__induction_predictive_equivalance_composition, \ + induction_predictive_implication_composition as temporal__induction_predictive_implication_composition, \ + induction_retrospective_equivalance_composition as temporal__induction_retrospective_equivalance_composition, \ + induction_retrospective_implication_composition as temporal__induction_retrospective_implication_composition, \ sequence as temporal__sequence, \ sequence_predictive_implication as temporal__sequence_predictive_implication diff --git a/pynars/NAL/MentalOperation/_execute.py b/pynars/NAL/MentalOperation/_execute.py index 9987a2e..b1be286 100644 --- a/pynars/NAL/MentalOperation/_execute.py +++ b/pynars/NAL/MentalOperation/_execute.py @@ -29,7 +29,7 @@ def believe(statement: Term, term_truth: Term): '''''' truth = truth_from_term(term_truth) budget = Budget(Config.p_judgement, Config.d_judgement, truth_to_quality(truth)) - stamp = Stamp(Global.time, Global.time, None, Base((Global.get_input_id(),))) + stamp = Stamp(Global.time, Global.time, None, Base((Global.get_input_id(),)), is_eternal=False) sentence = Judgement(statement, stamp=stamp, truth=truth) return Task(sentence, budget) @@ -45,7 +45,7 @@ def doubt(beliefs: List[Belief]): def evaluate(statement: Term): '''''' budget = Budget(Config.p_quest, Config.d_quest, 1.0) - stamp = Stamp(Global.time, Global.time, None, Base((Global.get_input_id(),))) + stamp = Stamp(Global.time, Global.time, None, Base((Global.get_input_id(),)), is_eternal=False) sentence = Quest(statement, stamp=stamp) return Task(sentence, budget) @@ -62,7 +62,7 @@ def want(statement: Term): '''''' truth = Truth(1.0, Config.c_judgement, Config.k) budget = Budget(Config.p_judgement, Config.d_judgement, truth_to_quality(truth)) - stamp = Stamp(Global.time, Global.time, None, Base((Global.get_input_id(),))) + stamp = Stamp(Global.time, Global.time, None, Base((Global.get_input_id(),)), is_eternal=False) sentence = Goal(statement, stamp, truth) return Task(sentence, budget) @@ -70,7 +70,7 @@ def want(statement: Term): def wonder(statement: Term): '''''' budget = Budget(Config.p_question, Config.d_question, 1) - stamp = Stamp(Global.time, Global.time, None, Base((Global.get_input_id(),))) + stamp = Stamp(Global.time, Global.time, None, Base((Global.get_input_id(),)), is_eternal=False) sentence = Question(statement, stamp=stamp) return Task(sentence, budget) diff --git a/pynars/NAL/_generate_init_file.py b/pynars/NAL/_generate_init_file.py index 794a659..44ad0df 100644 --- a/pynars/NAL/_generate_init_file.py +++ b/pynars/NAL/_generate_init_file.py @@ -19,7 +19,7 @@ pass content = "'''This file is generated by `_generate_init_file.py`'''\n\n\n" for path in module_names: - module = importlib.import_module(f'NAL.{name_module}.{path.stem}') + module = importlib.import_module(f'pynars.NAL.{name_module}.{path.stem}') funcs = [mem[0] for mem in getmembers(module, isfunction) if mem[1].__module__ == module.__name__] if len(funcs) == 0: continue diff --git a/pynars/NARS/Control/Reasoner_OpenNARS_3_0_4.py b/pynars/NARS/Control/Reasoner.py similarity index 98% rename from pynars/NARS/Control/Reasoner_OpenNARS_3_0_4.py rename to pynars/NARS/Control/Reasoner.py index 030b0c3..b260197 100644 --- a/pynars/NARS/Control/Reasoner_OpenNARS_3_0_4.py +++ b/pynars/NARS/Control/Reasoner.py @@ -100,7 +100,7 @@ def cycle(self): self.memory.put_back(concept) # temporal induction in NAL-7 - if task is not None and task.is_judgement and task.is_event: + if task is not None and task.is_judgement and task.is_external_event: concept_task: Concept = self.memory.take_by_key(task.term, remove=False) tasks_derived.extend( self.temporal_inference.step( diff --git a/pynars/NARS/Control/__init__.py b/pynars/NARS/Control/__init__.py index 5beba0a..8f1738e 100644 --- a/pynars/NARS/Control/__init__.py +++ b/pynars/NARS/Control/__init__.py @@ -1 +1 @@ -from .Reasoner_OpenNARS_3_0_4 import Reasoner as Reasoner_3_0_4 \ No newline at end of file +from .Reasoner import Reasoner \ No newline at end of file diff --git a/pynars/NARS/InferenceEngine/Engine.py b/pynars/NARS/InferenceEngine/Engine.py index 491eea6..42f6278 100644 --- a/pynars/NARS/InferenceEngine/Engine.py +++ b/pynars/NARS/InferenceEngine/Engine.py @@ -4,15 +4,13 @@ from pynars.Narsese._py.Term import Term from ..DataStructures import Task, Belief, Concept, TaskLink, TermLink from typing import Callable, List, Tuple -from ..RuleMap import RuleCallable, RuleMap_v2 +from ..RuleMap import RuleCallable, RuleMap from pynars.NAL.Inference import local__revision from pynars import Global class Engine: - - rule_map = RuleMap_v2() - + rule_map: RuleMap def __init__(self): pass @@ -23,4 +21,7 @@ def match(cls, *args, **kwargs): def step(self, *args, **kwargs): - pass \ No newline at end of file + pass + + def build(self): + self.rule_map.build() \ No newline at end of file diff --git a/pynars/NARS/InferenceEngine/GeneralEngine.py b/pynars/NARS/InferenceEngine/GeneralEngine.py deleted file mode 100644 index 8d4313a..0000000 --- a/pynars/NARS/InferenceEngine/GeneralEngine.py +++ /dev/null @@ -1,125 +0,0 @@ -from copy import copy -from pynars.NAL.Functions.Tools import project_truth, revisible -from pynars.Narsese._py.Budget import Budget -from pynars.Narsese._py.Term import Term -from ..DataStructures import Task, Belief, Concept, TaskLink, TermLink -from typing import Callable, List, Tuple -from ..RuleMap import RuleCallable, RuleMap_v2 -from pynars.NAL.Inference import local__revision -from pynars import Global -from .Engine import Engine - - -class GeneralEngine(Engine): - - # rule_map = RuleMap_v2() - - def __init__(self): - '''''' - super().__init__() - - - @classmethod - def match(cls, task: Task, belief: Belief, belief_term: Term, task_link, term_link): - '''To verify whether the task and the belief can interact with each other''' - - is_valid = False - is_revision = False - rules = [] - if belief is not None: - if task == belief: - if task.sentence.punct == belief.sentence.punct: - is_revision = revisible(task, belief) - elif task.term.equal(belief.term): - # TODO: here - pass - elif not belief.evidential_base.is_overlaped(task.evidential_base): - # Engine.rule_map.verify(task_link, term_link) - rules = GeneralEngine.rule_map.match(task, belief, belief_term, task_link, term_link) - if rules is not None and len(rules) > 0: - is_valid = True - elif belief_term is not None: # belief is None - if task.term == belief_term:pass - elif task.term.equal(belief_term): pass - else: - rules = GeneralEngine.rule_map.match(task, belief, belief_term, task_link, term_link) - if rules is not None and len(rules) > 0: - is_valid = True - else: # belief is None and belief_term is None - rules = GeneralEngine.rule_map.match(task, belief, belief_term, task_link, term_link) - if rules is not None and len(rules) > 0: - is_valid = True - - return is_valid, is_revision, rules - - - def step(self, concept: Concept): - '''One step inference.''' - tasks_derived = [] - - # Based on the selected concept, take out a task and a belief for further inference. - task_link_valid: TaskLink = concept.task_links.take(remove=True) - if task_link_valid is None: return tasks_derived - concept.task_links.put_back(task_link_valid) - - task: Task = task_link_valid.target - - # inference for single-premise rules - is_valid, _, rules_immediate = GeneralEngine.match(task, None, None, task_link_valid, None) - if is_valid: - tasks = self.inference(task, None, None, task_link_valid, None, rules_immediate) - tasks_derived.extend(tasks) - - # inference for two-premises rules - term_links = [] - term_link_valid = None - is_valid = False - for _ in range(len(concept.term_links)): - #To find a belief, which is valid to interact with the task, by iterating over the term-links. - term_link: TaskLink = concept.term_links.take(remove=True) - term_links.append(term_link) - - concept_target: Concept = term_link.target - belief = concept_target.get_belief() # TODO: consider all beliefs. - term_belief = concept_target.term - # if belief is None: continue - # Verify the validity of the interaction, and find a pair which is valid for inference. - is_valid, is_revision, rules = GeneralEngine.match(task, belief, term_belief, task_link_valid, term_link) - if is_revision: tasks_derived.append(local__revision(task, belief, task_link_valid.budget, term_link.budget)) - if is_valid: - term_link_valid = term_link - break - - - if is_valid: - tasks = self.inference(task, belief, term_belief, task_link_valid, term_link_valid, rules) - if term_link_valid is not None: # TODO: Check here whether the budget updating is the same as OpenNARS 3.0.4. - for task in tasks: TermLink.update_budget(term_link_valid.budget, task.budget.quality, belief.budget.priority if belief is not None else concept_target.budget.priority) - - tasks_derived.extend(tasks) - - for term_link in term_links: concept.term_links.put_back(term_link) - - return tasks_derived - - @staticmethod - def inference(task: Task, belief: Belief, term_belief: Term, task_link: TaskLink, term_link: TermLink, rules: List[RuleCallable]) -> List[Task]: # Tuple[List[Task], List[Tuple[Budget, float, float]]]: - ''' - It should be ensured that - 1. the task and the belief can interact with each other; - 2. the task is the target node of the task-link, and the concept correspoding to the belief is the target node of the term-link. - 3. there is a function, indexed by the task_link and the term_link, in the RuleMap. - ''' - # Temporal Projection and Eternalization - if belief is not None: - # TODO: Hanlde the backward inference. - if not belief.is_eternal and (belief.is_judgement or belief.is_goal): - truth_belief = project_truth(task.sentence, belief.sentence) - belief = belief.eternalize(truth_belief) - # beleif_eternalized = belief # TODO: should it be added into the `tasks_derived`? - - belief = belief if belief is not None else term_belief - tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] - - return tasks_derived - diff --git a/pynars/NARS/RuleMap/RuleMap_v2.py b/pynars/NARS/InferenceEngine/GeneralEngine/GeneralEngine.py similarity index 57% rename from pynars/NARS/RuleMap/RuleMap_v2.py rename to pynars/NARS/InferenceEngine/GeneralEngine/GeneralEngine.py index 60d0caf..f2252fa 100644 --- a/pynars/NARS/RuleMap/RuleMap_v2.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/GeneralEngine.py @@ -1,36 +1,31 @@ -from operator import imod -import os -from pathlib import Path -from inspect import getmembers, isfunction -import importlib -import re -from typing import Any, List, Tuple, Union -from typing_extensions import Protocol -from collections import OrderedDict - -from numpy import product - -from pynars.Config import Enable -from pynars.Narsese import Copula, Task -from pynars.Narsese import Connector, Statement, Belief, Term, Truth, Compound, Budget -from ..DataStructures import LinkType, TaskLink, TermLink -from pynars.NAL.Inference import * -from pynars.utils.SparseLUT import SparseLUT -from pynars.utils.tools import get_size - -from pynars.utils.Print import out_print, PrintType - -import time -from datetime import datetime -import pickle -import sty -from ._extract_feature import extract_feature, _compound_has_common, _compound_at +from copy import copy +from pynars.NAL.Functions.Tools import project_truth, revisible +from pynars.NARS.DataStructures._py.Link import LinkType +from .Rules import * +from ...RuleMap.add_rule import _compound_has_common, _compound_at, _at, _common +from pynars.NARS.RuleMap.add_rule import CommonId +from pynars.Narsese._py.Budget import Budget +from pynars.Narsese._py.Connector import Connector +from pynars.Narsese._py.Copula import Copula +from pynars.Narsese._py.Term import Term +from ...DataStructures import Task, Belief, Concept, TaskLink, TermLink +from typing import Callable, List, Tuple +from ...RuleMap import RuleCallable, RuleMap +from pynars.NAL.Inference import local__revision from pynars import Global +from ..Engine import Engine +from .extract_feature import extract_feature +from pathlib import Path -from .Rules import * -class RuleMap: - def __init__(self, build=True, add_rules={1,2,3,4,5,6,7,8,9}) -> None: +class GeneralEngine(Engine): + + rule_map = RuleMap(name='LUT', root_rules=Path(__file__).parent/'Rules') + + def __init__(self, build=True, add_rules={1,2,3,4,5,6,7,8,9}): + '''''' + super().__init__() + n_link_types = max([t.value for t in LinkType.__members__.values()]) n_copula = len(Copula) n_has_common_id = 2 @@ -51,7 +46,7 @@ def __init__(self, build=True, add_rules={1,2,3,4,5,6,7,8,9}) -> None: n_p1_at_p2 = 2 n_p2_at_p1 = 2 - self._init_type_map( + self.rule_map.init_type( ("is_belief_valid", bool, n_is_belief_valid), ("sentence_type", int, n_sentence_type), @@ -85,87 +80,58 @@ def __init__(self, build=True, add_rules={1,2,3,4,5,6,7,8,9}) -> None: ) - add_rules__NAL1(self.map, self.structure_map) if 1 in add_rules else None - add_rules__NAL2(self.map, self.structure_map) if 2 in add_rules else None - add_rules__NAL3(self.map, self.structure_map) if 3 in add_rules else None - add_rules__NAL4(self.map, self.structure_map) if 4 in add_rules else None - add_rules__NAL5(self.map, self.structure_map) if 5 in add_rules else None - add_rules__NAL6(self.map, self.structure_map) if 6 in add_rules else None - add_rules__NAL7(self.map, self.structure_map) if 7 in add_rules else None - add_rules__NAL8(self.map, self.structure_map) if 8 in add_rules else None - add_rules__NAL9(self.map, self.structure_map) if 9 in add_rules else None - - self.build() if build else None - + map = self.rule_map.map + structure = self.rule_map.structure + add_rules__NAL1(map, structure) if 1 in add_rules else None + add_rules__NAL2(map, structure) if 2 in add_rules else None + add_rules__NAL3(map, structure) if 3 in add_rules else None + add_rules__NAL4(map, structure) if 4 in add_rules else None + add_rules__NAL5(map, structure) if 5 in add_rules else None + add_rules__NAL6(map, structure) if 6 in add_rules else None + add_rules__NAL7(map, structure) if 7 in add_rules else None + add_rules__NAL8(map, structure) if 8 in add_rules else None + add_rules__NAL9(map, structure) if 9 in add_rules else None + + if build: self.build() pass - def _init_type_map(self, *slots: Tuple[object, str, int]): - ''' - slots (List[Tuple[object, str, int]]): each slot is filled in with the type, which is a int number, of an object. - ''' - self.structure_map = OrderedDict([(slot[0], tuple(slot[1:])) for slot in slots]) - # self.map = np.empty([n_type for *_, n_type in slots], dtype=object) # Shape: [LinkType, LinkType, Copula, Copula, match_reverse, common_id, Connector, Connector]. It cost about 1.2GB in memory... it's too expensive. So we have to adopt a more economic way. - shape = tuple([n_type for *_, n_type in slots]) - self.map = SparseLUT(shape) - pass - - - def build(self, clear=True): - root_path = Path(__file__).parent - def check_update(): - cache_path = root_path/'LUT.pkl' - try: - if not cache_path.exists(): return True - this_filepath = Path(__file__) - filepaths = (this_filepath.parent/"Rules").glob("NAL*.py") - mtime_cache = datetime.fromtimestamp(cache_path.stat().st_mtime) - for filepath in filepaths: - mtime_this = datetime.fromtimestamp(filepath.stat().st_mtime) - if mtime_this > mtime_cache: - return True - return False - except: - if not cache_path.exists(): return True - else: return False - - if check_update(): - # t_start = time.time() - # self.map.build(clear) - # t_end = time.time() - # self.map.dump(str(root_path)) - # if Enable.debug: out_print(PrintType.INFO, f'Building time cost: {t_end-t_start}s.') - self.rebuild(root_path, clear) - else: - self.load(str(root_path)) - - # if Enable.debug: out_print(PrintType.INFO, f'The size of map: {get_size(self.map.lut)/1024/1024:.6f}MB') - - def load(self, root_path: str): - if Enable.debug: out_print(PrintType.INFO, f'Loading RuleMap...') - t_start = time.time() - self.map.load(str(root_path)) - t_end = time.time() - if Enable.debug: out_print(PrintType.INFO, f'Done. Time-cost: {t_end-t_start}s.') - - def rebuild(self, root_path: str, clear=True): - '''''' - if Enable.debug: out_print(PrintType.INFO, f'Building RuleMap...') - t_start = time.time() - self.map.build(clear) - t_end = time.time() - if Enable.debug: out_print(PrintType.INFO, f'Done. Time-cost: {t_end-t_start}s.') - if Enable.debug: out_print(PrintType.INFO, f'Saving RuleMap...') - self.map.dump(str(root_path)) - if Enable.debug: out_print(PrintType.INFO, f'Done.') - - - def draw(self, show_labels=True): - self.map.draw(show_labels) - + @classmethod + def match(cls, task: Task, belief: Belief, belief_term: Term, task_link, term_link): + '''To verify whether the task and the belief can interact with each other''' - def match(self, task: Task, belief: Union[Belief, None], belief_term: Union[Term, Compound, Statement, None], task_link: TaskLink, term_link: TermLink): + is_valid = False + is_revision = False + rules = [] + if belief is not None: + if task == belief: + if task.sentence.punct == belief.sentence.punct: + is_revision = revisible(task, belief) + elif task.term.equal(belief.term): + # TODO: here + pass + elif not belief.evidential_base.is_overlaped(task.evidential_base): + # Engine.rule_map.verify(task_link, term_link) + rules = GeneralEngine.match_rule(task, belief, belief_term, task_link, term_link) + if rules is not None and len(rules) > 0: + is_valid = True + elif belief_term is not None: # belief is None + if task.term == belief_term:pass + elif task.term.equal(belief_term): pass + else: + rules = GeneralEngine.match_rule(task, belief, belief_term, task_link, term_link) + if rules is not None and len(rules) > 0: + is_valid = True + else: # belief is None and belief_term is None + rules = GeneralEngine.match_rule(task, belief, belief_term, task_link, term_link) + if rules is not None and len(rules) > 0: + is_valid = True + + return is_valid, is_revision, rules + + @classmethod + def match_rule(cls, task: Task, belief: Union[Belief, None], belief_term: Union[Term, Compound, Statement, None], task_link: TaskLink, term_link: TermLink): ''' Given a task and a belief, find the matched rules for one step inference. ''' @@ -233,20 +199,20 @@ def match(self, task: Task, belief: Union[Belief, None], belief_term: Union[Term # Now, `belief` is None compound_common_id = feature.compound_common_id_task connector2 = belief_term.connector - - common_term = task.term[compound_common_id] - if belief_term.is_double_only: - if common_term == belief_term[0]: - at_compound_pos = 0 - elif common_term == belief_term[1]: - at_compound_pos = 1 - else: raise "Invalid case." - elif belief_term.is_multiple_only: - if common_term == belief_term[0]: - at_compound_pos = 0 - else: - at_compound_pos = 1 - pass + if compound_common_id is not None: + common_term = task.term[compound_common_id] + if belief_term.is_double_only: + if common_term == belief_term[0]: + at_compound_pos = 0 + elif common_term == belief_term[1]: + at_compound_pos = 1 + else: raise "Invalid case." + elif belief_term.is_multiple_only: + if common_term == belief_term[0]: + at_compound_pos = 0 + else: + at_compound_pos = 1 + pass elif feature.compound_common_id_task is None: # Now, `task` is None @@ -330,7 +296,7 @@ def match(self, task: Task, belief: Union[Belief, None], belief_term: Union[Term link2.value if link2 is not None else None, int(task.term.copula) if not task.term.is_atom else None, - int(belief.term.copula) if belief is not None else (int(belief_term.connector) if ((belief_term is not None) and (not belief_term.is_atom) and belief_term.is_compound) else None), + int(belief.term.copula) if (belief is not None and belief_term.is_statement) else (int(belief_term.connector) if (belief_term is not None and belief_term.is_compound) else None), int(connector1) if connector1 is not None else None, int(connector2) if connector2 is not None else None, @@ -352,41 +318,76 @@ def match(self, task: Task, belief: Union[Belief, None], belief_term: Union[Term ) - rules: RuleCallable = self.map[indices] + rules: RuleCallable = cls.rule_map[indices] return rules + def step(self, concept: Concept): + '''One step inference.''' + tasks_derived = [] + + # Based on the selected concept, take out a task and a belief for further inference. + task_link_valid: TaskLink = concept.task_links.take(remove=True) + if task_link_valid is None: return tasks_derived + concept.task_links.put_back(task_link_valid) + + task: Task = task_link_valid.target + + # inference for single-premise rules + is_valid, _, rules_immediate = GeneralEngine.match(task, None, None, task_link_valid, None) + if is_valid: + tasks = self.inference(task, None, None, task_link_valid, None, rules_immediate) + tasks_derived.extend(tasks) + + # inference for two-premises rules + term_links = [] + term_link_valid = None + is_valid = False + for _ in range(len(concept.term_links)): + #To find a belief, which is valid to interact with the task, by iterating over the term-links. + term_link: TaskLink = concept.term_links.take(remove=True) + term_links.append(term_link) + + concept_target: Concept = term_link.target + belief = concept_target.get_belief() # TODO: consider all beliefs. + term_belief = concept_target.term + # if belief is None: continue + # Verify the validity of the interaction, and find a pair which is valid for inference. + is_valid, is_revision, rules = GeneralEngine.match(task, belief, term_belief, task_link_valid, term_link) + if is_revision: tasks_derived.append(local__revision(task, belief, task_link_valid.budget, term_link.budget)) + if is_valid: + term_link_valid = term_link + break + + + if is_valid: + tasks = self.inference(task, belief, term_belief, task_link_valid, term_link_valid, rules) + if term_link_valid is not None: # TODO: Check here whether the budget updating is the same as OpenNARS 3.0.4. + for task in tasks: TermLink.update_budget(term_link_valid.budget, task.budget.quality, belief.budget.priority if belief is not None else concept_target.budget.priority) + + tasks_derived.extend(tasks) + + for term_link in term_links: concept.term_links.put_back(term_link) + + return tasks_derived - def verify(self, task_link: TaskLink, term_link: TermLink, *args): - raise "Invalid function." - - - def diagnose(self, indices): + @staticmethod + def inference(task: Task, belief: Belief, term_belief: Term, task_link: TaskLink, term_link: TermLink, rules: List[RuleCallable]) -> List[Task]: # Tuple[List[Task], List[Tuple[Budget, float, float]]]: ''' - Given a `indices`, check whether a valid rule can be retrieved. - If not, return the index of the position where an error occurs. - Else, return None. - In each case, Prompt message is printed. + It should be ensured that + 1. the task and the belief can interact with each other; + 2. the task is the target node of the task-link, and the concept correspoding to the belief is the target node of the term-link. + 3. there is a function, indexed by the task_link and the term_link, in the RuleMap. ''' - for i in range(1,len(indices)): - if self.map[indices[:i]] is None: - name_str, (name_type, _) = list(self.structure_map.items())[i] - print(f"{sty.fg.blue}Diagnose: {sty.fg.red}ERROR.\n {sty.fg.blue}{i}: {sty.ef.bold}{name_str}, {name_type}{sty.rs.all}") - - return i - print(f"{sty.fg.blue}Diagnose: {sty.fg.green}PASS.{sty.rs.all}") - return None + # Temporal Projection and Eternalization + if belief is not None: + # TODO: Hanlde the backward inference. + if not belief.is_eternal and (belief.is_judgement or belief.is_goal): + truth_belief = project_truth(task.sentence, belief.sentence) + belief = belief.eternalize(truth_belief) + # beleif_eternalized = belief # TODO: should it be added into the `tasks_derived`? + belief = belief if belief is not None else term_belief + tasks_derived = [rule(task, belief, task_link, term_link) for rule in rules] - def __repr__(self) -> str: - '''print self.type_map''' - r = f"\n" - for key, item in self.structure_map.items(): - r += f" {key}, {item}\n" - return r - - + return tasks_derived -if __name__ == '__main__': - root_path = Path(__file__).parent - rulemap = RuleMap(build=False) - rulemap.rebuild(root_path) diff --git a/pynars/NARS/RuleMap/Rules/NAL1.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL1.py similarity index 99% rename from pynars/NARS/RuleMap/Rules/NAL1.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL1.py index f91ba62..bce1fb7 100644 --- a/pynars/NARS/RuleMap/Rules/NAL1.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL1.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink from pynars.utils.SparseLUT import SparseLUT from pynars import Global -from .add_rule import * +from ....RuleMap.add_rule import * def add_rules__NAL1(sparse_lut: SparseLUT, structure: OrderedDict): diff --git a/pynars/NARS/RuleMap/Rules/NAL2.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL2.py similarity index 99% rename from pynars/NARS/RuleMap/Rules/NAL2.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL2.py index f8b7b72..d6850e3 100644 --- a/pynars/NARS/RuleMap/Rules/NAL2.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL2.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink from pynars.utils.SparseLUT import SparseLUT from pynars import Global -from .add_rule import * +from ....RuleMap.add_rule import * def add_rules__NAL2(sparse_lut: SparseLUT, structure: OrderedDict): diff --git a/pynars/NARS/RuleMap/Rules/NAL3.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL3.py similarity index 99% rename from pynars/NARS/RuleMap/Rules/NAL3.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL3.py index 36e6107..731e140 100644 --- a/pynars/NARS/RuleMap/Rules/NAL3.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL3.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink from pynars.utils.SparseLUT import SparseLUT from pynars import Global -from .add_rule import * +from ....RuleMap.add_rule import * def add_rules__NAL3(sparse_lut: SparseLUT, structure: OrderedDict): '''''' diff --git a/pynars/NARS/RuleMap/Rules/NAL4.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL4.py similarity index 99% rename from pynars/NARS/RuleMap/Rules/NAL4.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL4.py index 59a5414..248ea43 100644 --- a/pynars/NARS/RuleMap/Rules/NAL4.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL4.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink from pynars.utils.SparseLUT import SparseLUT from pynars import Global -from .add_rule import * +from ....RuleMap.add_rule import * def add_rules__NAL4(sparse_lut: SparseLUT, structure: OrderedDict): diff --git a/pynars/NARS/RuleMap/Rules/NAL5.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL5.py similarity index 89% rename from pynars/NARS/RuleMap/Rules/NAL5.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL5.py index 4f7cf6a..79b89d6 100644 --- a/pynars/NARS/RuleMap/Rules/NAL5.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL5.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink from pynars.utils.SparseLUT import SparseLUT from pynars import Global -from .add_rule import * +from ....RuleMap.add_rule import * def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): @@ -20,7 +20,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, Copula2 = Copula.Implication, match_reverse = False, - common_id = CommonId(0, 1) + common_id = CommonId(0, 1), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -31,7 +32,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, Copula2 = Copula.Implication, match_reverse = False, - common_id = CommonId(1, 0) + common_id = CommonId(1, 0), + is_belief_valid = True, ) '''exemplification''' @@ -43,7 +45,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, Copula2 = Copula.Implication, match_reverse = False, - common_id = CommonId(0, 1) + common_id = CommonId(0, 1), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -54,7 +57,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, Copula2 = Copula.Implication, match_reverse = False, - common_id = CommonId(1, 0) + common_id = CommonId(1, 0), + is_belief_valid = True, ) '''induction''' @@ -66,7 +70,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, Copula2 = Copula.Implication, match_reverse = False, - common_id = CommonId(0, 0) + common_id = CommonId(0, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -77,7 +82,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, Copula2 = Copula.Implication, match_reverse = False, - common_id = CommonId(0, 0) + common_id = CommonId(0, 0), + is_belief_valid = True, ) '''abduction''' @@ -89,7 +95,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, Copula2 = Copula.Implication, match_reverse = False, - common_id = CommonId(1, 1) + common_id = CommonId(1, 1), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -100,7 +107,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, Copula2 = Copula.Implication, match_reverse = False, - common_id = CommonId(1, 1) + common_id = CommonId(1, 1), + is_belief_valid = True, ) '''reversion''' @@ -111,7 +119,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): has_common_id = True, Copula1 = Copula.Implication, Copula2 = Copula.Implication, - match_reverse = True + match_reverse = True, + is_belief_valid = True, ) @@ -125,7 +134,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, # ==> Copula2 = Copula.Implication, # ==> match_reverse = False, - common_id = CommonId(0, 0) + common_id = CommonId(0, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -136,7 +146,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, # ==> Copula2 = Copula.Implication, # ==> match_reverse = False, - common_id = CommonId(0, 0) + common_id = CommonId(0, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -147,7 +158,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, # ==> Copula2 = Copula.Implication, # ==> match_reverse = False, - common_id = CommonId(1, 1) + common_id = CommonId(1, 1), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -158,7 +170,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, # ==> Copula2 = Copula.Implication, # ==> match_reverse = False, - common_id = CommonId(1, 1) + common_id = CommonId(1, 1), + is_belief_valid = True, ) '''analogy''' add_rule(sparse_lut, structure, @@ -169,7 +182,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, # ==> Copula2 = Copula.Equivalence, # <=> match_reverse = False, - common_id = CommonId(0, 0) + common_id = CommonId(0, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -180,7 +194,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, # ==> Copula2 = Copula.Equivalence, # <=> match_reverse = False, - common_id = CommonId(0, 1) + common_id = CommonId(0, 1), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -191,7 +206,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, # ==> Copula2 = Copula.Equivalence, # <=> match_reverse = False, - common_id = CommonId(1, 0) + common_id = CommonId(1, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -202,7 +218,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Implication, # ==> Copula2 = Copula.Equivalence, # <=> match_reverse = False, - common_id = CommonId(1, 1) + common_id = CommonId(1, 1), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -213,7 +230,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Equivalence, # <=> Copula2 = Copula.Implication, # ==> match_reverse = False, - common_id = CommonId(0, 0) + common_id = CommonId(0, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -224,7 +242,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Equivalence, # <=> Copula2 = Copula.Implication, # ==> match_reverse = False, - common_id = CommonId(0, 1) + common_id = CommonId(0, 1), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -235,7 +254,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Equivalence, # <=> Copula2 = Copula.Implication, # ==> match_reverse = False, - common_id = CommonId(1, 0) + common_id = CommonId(1, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -246,7 +266,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Equivalence, # <=> Copula2 = Copula.Implication, # ==> match_reverse = False, - common_id = CommonId(1, 1) + common_id = CommonId(1, 1), + is_belief_valid = True, ) '''resemblance''' add_rule(sparse_lut, structure, @@ -257,7 +278,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Equivalence, # <=> Copula2 = Copula.Equivalence, # <=> match_reverse = False, - common_id = CommonId(0, 0) + common_id = CommonId(0, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -268,7 +290,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Equivalence, # <=> Copula2 = Copula.Equivalence, # <=> match_reverse = False, - common_id = CommonId(0, 1) + common_id = CommonId(0, 1), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -279,7 +302,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Equivalence, # <=> Copula2 = Copula.Equivalence, # <=> match_reverse = False, - common_id = CommonId(1, 0) + common_id = CommonId(1, 0), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -290,7 +314,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula1 = Copula.Equivalence, # <=> Copula2 = Copula.Equivalence, # <=> match_reverse = False, - common_id = CommonId(1, 1) + common_id = CommonId(1, 1), + is_belief_valid = True, ) '''---------NAL 3---------''' @@ -314,7 +339,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula2 = Copula.Implication, match_reverse = False, common_id = CommonId(0, 0), - sentence_type = class_sentence_to_list(Judgement) + sentence_type = class_sentence_to_list(Judgement), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -332,7 +358,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula2 = Copula.Implication, match_reverse = False, common_id = CommonId(1, 1), - sentence_type = class_sentence_to_list(Judgement) + sentence_type = class_sentence_to_list(Judgement), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -350,7 +377,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula2 = Copula.Implication, match_reverse = False, common_id = CommonId(0, 0), - sentence_type = class_sentence_to_list(Judgement) + sentence_type = class_sentence_to_list(Judgement), + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -368,7 +396,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula2 = Copula.Implication, match_reverse = False, common_id = CommonId(1, 1), - sentence_type = class_sentence_to_list(Judgement) + sentence_type = class_sentence_to_list(Judgement), + is_belief_valid = True, ) ''' @@ -389,7 +418,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): the_other_compound_p1_at_p2 = False, the_other_compound_p2_at_p1 = True, Connector1 = Connector.Conjunction, - Connector2 = Any + Connector2 = Any, + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -406,7 +436,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): the_other_compound_p1_at_p2 = True, the_other_compound_p2_at_p1 = False, Connector1 = Any, - Connector2 = Connector.Conjunction + Connector2 = Connector.Conjunction, + is_belief_valid = True, ) @@ -427,7 +458,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): match_reverse = False, common_id = CommonId(0), has_at = True, - p2_at_p1=True + p2_at_p1=True, + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -440,7 +472,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): match_reverse = False, common_id = CommonId(0), has_at = True, - p1_at_p2=True + p1_at_p2=True, + is_belief_valid = True, ) '''deduction (compound eliminate)''' add_rule(sparse_lut, structure, @@ -488,7 +521,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula2 = Copula.Implication, match_reverse = False, compound_common_id = CommonId(0, 1), - Connector1 = Connector.Conjunction + Connector1 = Connector.Conjunction, + is_belief_valid = True, ) @@ -508,7 +542,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula2 = Copula.Implication, match_reverse = False, compound_common_id = CommonId(1, 0), - Connector2 = Connector.Conjunction + Connector2 = Connector.Conjunction, + is_belief_valid = True, ) '''abduction''' @@ -522,7 +557,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): match_reverse = False, common_id = CommonId(1), has_at = True, - p2_at_p1=True + p2_at_p1=True, + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -535,7 +571,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): match_reverse = False, common_id = CommonId(1), has_at = True, - p1_at_p2=True + p1_at_p2=True, + is_belief_valid = True, ) '''abudction (compound eliminate)''' @@ -558,7 +595,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): the_other_compound_p1_at_p2 = False, the_other_compound_p2_at_p1 = True, Connector1 = Connector.Conjunction, - Connector2 = None + Connector2 = None, + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -580,7 +618,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): the_other_compound_p1_at_p2 = True, the_other_compound_p2_at_p1 = False, Connector1 = None, - Connector2 = Connector.Conjunction + Connector2 = Connector.Conjunction, + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -605,7 +644,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): the_other_compound_p1_at_p2 = True, the_other_compound_p2_at_p1 = True, Connector1 = Connector.Conjunction, - Connector2 = Connector.Conjunction + Connector2 = Connector.Conjunction, + is_belief_valid = True, ) '''induction (compound replace)''' @@ -625,7 +665,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula2 = Copula.Implication, match_reverse = False, compound_common_id = CommonId(0, 0), - Connector1 = Connector.Conjunction + Connector1 = Connector.Conjunction, + is_belief_valid = True, ) @@ -645,7 +686,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): Copula2 = Copula.Implication, match_reverse = False, compound_common_id = CommonId(0, 0), - Connector2 = Connector.Conjunction + Connector2 = Connector.Conjunction, + is_belief_valid = True, ) '''analogy''' @@ -659,7 +701,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): match_reverse = False, common_id = CommonId(0), has_at = True, - p1_at_p2=True + p1_at_p2=True, + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -672,7 +715,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): match_reverse = False, common_id = CommonId(0), has_at = True, - p2_at_p1=True + p2_at_p1=True, + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -685,7 +729,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): match_reverse = False, common_id = CommonId(1), has_at = True, - p1_at_p2=True + p1_at_p2=True, + is_belief_valid = True, ) add_rule(sparse_lut, structure, @@ -698,7 +743,8 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): match_reverse = False, common_id = CommonId(1), has_at = True, - p2_at_p1=True + p2_at_p1=True, + is_belief_valid = True, ) ''' @@ -793,7 +839,7 @@ def add_rules__NAL5(sparse_lut: SparseLUT, structure: OrderedDict): # LinkType2 = LinkType.COMPOUND, Connector1 = Connector.Conjunction, p2_at_p1 = True, - is_belief_valid = False + is_belief_valid = False, ) add_rule(sparse_lut, structure, diff --git a/pynars/NARS/RuleMap/Rules/NAL6.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL6.py similarity index 88% rename from pynars/NARS/RuleMap/Rules/NAL6.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL6.py index 8b3097c..67749c3 100644 --- a/pynars/NARS/RuleMap/Rules/NAL6.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL6.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink from pynars.utils.SparseLUT import SparseLUT from pynars import Global -from .add_rule import * +from ....RuleMap.add_rule import * def add_rules__NAL6(sparse_lut: SparseLUT, structure: OrderedDict): diff --git a/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL7.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL7.py new file mode 100644 index 0000000..11a0b09 --- /dev/null +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL7.py @@ -0,0 +1,827 @@ +from collections import OrderedDict +from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink +from pynars.utils.SparseLUT import SparseLUT +from pynars import Global +from ....RuleMap.add_rule import * + + +def add_rules__NAL7(sparse_lut: SparseLUT, structure: OrderedDict): + '''''' + '''deduction''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__deduction__0_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, + Copula2 = Copula.RetrospectiveImplication, + match_reverse = False, + common_id = CommonId(0, 1), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__deduction__1_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, + Copula2 = Copula.RetrospectiveImplication, + match_reverse = False, + common_id = CommonId(1, 0), + is_belief_valid = True + ) + + '''exemplification''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__exemplification__0_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, + Copula2 = Copula.RetrospectiveImplication, + match_reverse = False, + common_id = CommonId(0, 1), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__exemplification__1_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, + Copula2 = Copula.RetrospectiveImplication, + match_reverse = False, + common_id = CommonId(1, 0), + is_belief_valid = True + ) + + '''induction''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__induction__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, + Copula2 = Copula.RetrospectiveImplication, + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__induction__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, + Copula2 = Copula.PredictiveImplication, + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__induction__0_0_prime, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, + Copula2 = Copula.RetrospectiveImplication, + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__induction__0_0_prime, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, + Copula2 = Copula.PredictiveImplication, + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True + ) + + '''abduction''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__abduction__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, # =/> + Copula2 = Copula.RetrospectiveImplication, # =\> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__abduction__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, # =\> + Copula2 = Copula.PredictiveImplication, # =/> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__abduction__1_1_prime, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, # =/> + Copula2 = Copula.RetrospectiveImplication, # =\> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__abduction__1_1_prime, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, # =\> + Copula2 = Copula.PredictiveImplication, # =/> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True + ) + + '''comparison''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__comparison__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, # =/> + Copula2 = Copula.RetrospectiveImplication, # =\> + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__comparison__0_0_prime, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, # =\> + Copula2 = Copula.PredictiveImplication, # =/> + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__comparison__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, # =/> + Copula2 = Copula.RetrospectiveImplication, # =\> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__comparison__1_1_prime, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, # =\> + Copula2 = Copula.PredictiveImplication, # =/> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True + ) + + '''analogy''' + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.RetrospectiveImplication, + Copula.ConcurrentImplication + ], # =\>, =|> + Copula2 = [ + Copula.PredictiveEquivalence, + Copula.ConcurrentEquivalence + ], # , <|> + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True, + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, # =/> + Copula2 = Copula.ConcurrentEquivalence, # <|> + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__0_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.PredictiveImplication, + Copula.ConcurrentImplication + ], # =/>, =|> + Copula2 = [ + Copula.PredictiveEquivalence, + Copula.ConcurrentEquivalence + ], # , <|> + match_reverse = False, + common_id = CommonId(0, 1), + is_belief_valid = True, + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__0_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.RetrospectiveImplication, # =\> + Copula2 = Copula.ConcurrentEquivalence, # <|> + match_reverse = False, + common_id = CommonId(0, 1), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__1_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.PredictiveImplication, + Copula.ConcurrentImplication + ], # =/>, =|> + Copula2 = [ + Copula.PredictiveEquivalence, + Copula.ConcurrentEquivalence + ], # , <|> + match_reverse = False, + common_id = CommonId(1, 0), + is_belief_valid = True, + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__1_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.RetrospectiveImplication, + ], # =\> + Copula2 = Copula.ConcurrentEquivalence, # <|> + match_reverse = False, + common_id = CommonId(1, 0), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.RetrospectiveImplication, + Copula.ConcurrentImplication + ], # =\>, =|> + Copula2 = [ + Copula.PredictiveEquivalence, + Copula.ConcurrentEquivalence + ], # , <|> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True, + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, # =/> + Copula2 = Copula.ConcurrentEquivalence, # <|> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True, + ) + + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.PredictiveEquivalence, + Copula.ConcurrentEquivalence + ], # , <|> + Copula2 = [ + Copula.RetrospectiveImplication, + Copula.ConcurrentImplication + ], # =\>, =|> + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True, + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentEquivalence, # <|> + Copula2 = Copula.PredictiveImplication, # =/> + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__0_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.PredictiveEquivalence, + Copula.ConcurrentEquivalence + ], # , <|> + Copula2 = [ + Copula.PredictiveImplication, + Copula.ConcurrentImplication + ], # =/>, =|> + match_reverse = False, + common_id = CommonId(0, 1), + is_belief_valid = True, + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__0_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentEquivalence, # <|> + Copula2 = Copula.RetrospectiveImplication, # =\> + match_reverse = False, + common_id = CommonId(0, 1), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__1_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.PredictiveEquivalence, + Copula.ConcurrentEquivalence + ], # , <|> + Copula2 = [ + Copula.PredictiveImplication, + Copula.ConcurrentImplication + ], # =/>, =|> + match_reverse = False, + common_id = CommonId(1, 0), + is_belief_valid = True, + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__1_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentEquivalence, # <|> + Copula2 = Copula.RetrospectiveImplication, # =\> + match_reverse = False, + common_id = CommonId(1, 0), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = [ + Copula.PredictiveEquivalence, + Copula.ConcurrentEquivalence + ], # , <|> + Copula2 = [ + Copula.RetrospectiveImplication, + Copula.ConcurrentImplication + ], # =\>, =|> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True, + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__analogy__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentEquivalence, # <|> + Copula2 = Copula.PredictiveImplication, # =/> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True, + ) + + + + '''reversion?''' + + '''---------------''' + + '''---------NAL 2---------''' + '''resemblance''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__resemblance__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentEquivalence, # <|> + Copula2 = Copula.ConcurrentEquivalence, # <|> + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__resemblance__0_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentEquivalence, # <|> + Copula2 = Copula.ConcurrentEquivalence, # <|> + match_reverse = False, + common_id = CommonId(0, 1), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__resemblance__1_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentEquivalence, # <|> + Copula2 = Copula.ConcurrentEquivalence, # <|> + match_reverse = False, + common_id = CommonId(1, 0), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__resemblance__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentEquivalence, # <|> + Copula2 = Copula.ConcurrentEquivalence, # <|> + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True, + ) + + '''---------NAL 5---------''' + + '''conditianal rules''' + + '''deduction''' + add_rule(sparse_lut, structure, + Interface_ConditionalRules._conditional__deduction__0, + LinkType1 = LinkType.COMPOUND_CONDITION, + # LinkType2 = LinkType.COMPOUND_STATEMENT, + has_common_id = True, + Copula1 = Copula.PredictiveImplication, + # Copula2 = Copula.PredictiveImplication, + match_reverse = False, + common_id = CommonId(0), + has_at = True, + p2_at_p1=True, + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_ConditionalRules._conditional__deduction__0_prime, + # LinkType1 = LinkType.COMPOUND_STATEMENT, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + # Copula1 = Copula.PredictiveImplication, + Copula2 = Copula.PredictiveImplication, + match_reverse = False, + common_id = CommonId(0), + has_at = True, + p1_at_p2=True, + is_belief_valid = True + ) + # '''deduction (compound eliminate)''' + # add_rule(sparse_lut, structure, + # Interface_ConditionalRules._conditional__deduction_compound_eliminate__0, + # LinkType1 = LinkType.COMPOUND_STATEMENT, + # LinkType2 = LinkType.COMPOUND_STATEMENT, + # has_common_id = True, + # has_compound_at = True, + # Copula1 = Copula.PredictiveImplication, + # # Copula2 = Copula.PredictiveImplication, + # match_reverse = False, + # common_id = CommonId(0), + # Connector1 = Connector.Conjunction + # ) + + # add_rule(sparse_lut, structure, + # Interface_ConditionalRules._conditional__deduction_compound_eliminate__0_prime, + # LinkType1 = LinkType.COMPOUND_STATEMENT, + # LinkType2 = LinkType.COMPOUND_STATEMENT, + # has_common_id = True, + # has_compound_at = True, + # # Copula1 = Copula.PredictiveImplication, + # Copula2 = Copula.PredictiveImplication, + # match_reverse = False, + # common_id = CommonId(0), + # Connector2 = Connector.Conjunction + # ) + + # '''deduction (compound replace)''' + # add_rule(sparse_lut, structure, + # Interface_ConditionalRules._conditional__deduction_compound_replace__0_1, + # LinkType1 = [ + # LinkType.COMPOUND_STATEMENT, + # LinkType.COMPOUND_CONDITION + # ], + # LinkType2 = [ + # LinkType.COMPOUND_STATEMENT, + # LinkType.COMPOUND_CONDITION + # ], + # has_common_id = True, + # has_compound_common_id = True, + # Copula1 = Copula.Implication, + # Copula2 = Copula.Implication, + # match_reverse = False, + # compound_common_id = CommonId(0, 1), + # Connector1 = Connector.Conjunction + # ) + + + # add_rule(sparse_lut, structure, + # Interface_ConditionalRules._conditional__deduction_compound_replace__1_0, + # LinkType1 = [ + # LinkType.COMPOUND_STATEMENT, + # LinkType.COMPOUND_CONDITION + # ], + # LinkType2 = [ + # LinkType.COMPOUND_STATEMENT, + # LinkType.COMPOUND_CONDITION + # ], + # has_common_id = True, + # has_compound_common_id = True, + # Copula1 = Copula.Implication, + # Copula2 = Copula.Implication, + # match_reverse = False, + # compound_common_id = CommonId(1, 0), + # Connector2 = Connector.Conjunction + # ) + + '''deduction''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__deduction__0_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentImplication, + Copula2 = Copula.ConcurrentImplication, + match_reverse = False, + common_id = CommonId(0, 1), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__deduction__1_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentImplication, + Copula2 = Copula.ConcurrentImplication, + match_reverse = False, + common_id = CommonId(1, 0), + is_belief_valid = True, + ) + + '''induction''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__induction__0_0, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentImplication, + Copula2 = Copula.ConcurrentImplication, + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__induction__0_0_prime, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentImplication, + Copula2 = Copula.ConcurrentImplication, + match_reverse = False, + common_id = CommonId(0, 0), + is_belief_valid = True, + ) + + '''abduction''' + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__abduction__1_1, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentImplication, + Copula2 = Copula.ConcurrentImplication, + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_SyllogisticRules._syllogistic__abduction__1_1_prime, + LinkType1 = LinkType.COMPOUND_CONDITION, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + Copula1 = Copula.ConcurrentImplication, + Copula2 = Copula.ConcurrentImplication, + match_reverse = False, + common_id = CommonId(1, 1), + is_belief_valid = True, + ) + + '''temporal contitional abduction''' + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__abduction__1, + LinkType1 = [ + LinkType.COMPOUND_CONDITION, + LinkType.COMPOUND_STATEMENT + ], + # LinkType2 = LinkType.COMPOUND_STATEMENT, + has_common_id = True, + Copula1 = [ + Copula.PredictiveImplication, + Copula.ConcurrentImplication, + Copula.RetrospectiveImplication + ], + # Copula2 = Copula.PredictiveImplication, + match_reverse = False, + common_id = CommonId(1), + has_at = True, + p2_at_p1=True, + is_belief_valid = True + ) + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__abduction__1_prime, + # LinkType1 = LinkType.COMPOUND_STATEMENT, + LinkType2 = [ + LinkType.COMPOUND_CONDITION, + LinkType.COMPOUND_STATEMENT + ], + has_common_id = True, + # Copula1 = Copula.PredictiveImplication, + Copula2 = [ + Copula.PredictiveImplication, + Copula.ConcurrentImplication, + Copula.RetrospectiveImplication + ], + match_reverse = False, + common_id = CommonId(1), + has_at = True, + p1_at_p2=True, + is_belief_valid = True + ) + + + '''---------NAL 5---------''' + + '''deduction''' + add_rule(sparse_lut, structure, + Interface_ConditionalRules._conditional__deduction__0, + LinkType1 = LinkType.COMPOUND_CONDITION, + # LinkType2 = LinkType.COMPOUND_STATEMENT, + has_common_id = True, + Copula1 = [ + Copula.ConcurrentImplication, + Copula.PredictiveImplication, + ], + # Copula2 = Copula.Implication, + match_reverse = False, + common_id = CommonId(0), + has_at = True, + p2_at_p1=True, + is_belief_valid = True, + ) + + add_rule(sparse_lut, structure, + Interface_ConditionalRules._conditional__deduction__0_prime, + # LinkType1 = LinkType.COMPOUND_STATEMENT, + LinkType2 = LinkType.COMPOUND_CONDITION, + has_common_id = True, + # Copula1 = Copula.Implication, + Copula2 = [ + Copula.ConcurrentImplication, + Copula.PredictiveImplication, + ], + match_reverse = False, + common_id = CommonId(0), + has_at = True, + p1_at_p2=True, + is_belief_valid = True, + ) + + + '''---------NAL 7---------''' + '''sequential conditional deduction (compound eliminate)''' + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__deduction_sequence_eliminate__0, + LinkType1 = [LinkType.COMPOUND_STATEMENT, LinkType.SELF], + LinkType2 = LinkType.COMPOUND_STATEMENT, + has_common_id = True, + has_compound_at = True, + Copula1 = Copula.PredictiveImplication, + # Copula2 = Copula.PredictiveImplication, + match_reverse = False, + common_id = CommonId(0), + Connector1 = Connector.SequentialEvents, + is_belief_valid=True + ) + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__deduction_sequence_eliminate__0_prime, + LinkType1 = [LinkType.COMPOUND_STATEMENT, LinkType.SELF], + LinkType2 = LinkType.COMPOUND_STATEMENT, + has_common_id = True, + has_compound_at = True, + # Copula1 = Copula.PredictiveImplication, + Copula2 = Copula.PredictiveImplication, + match_reverse = False, + common_id = CommonId(0), + Connector2 = Connector.SequentialEvents, + is_belief_valid=True + ) + + '''deduction (sequence replace)''' + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__deduction_sequence_replace__0_1, + LinkType1 = [ + LinkType.COMPOUND_STATEMENT, + LinkType.COMPOUND_CONDITION + ], + LinkType2 = [ + LinkType.COMPOUND_STATEMENT, + LinkType.COMPOUND_CONDITION + ], + has_common_id = True, + has_compound_common_id = True, + Copula1 = Copula.PredictiveImplication, + Copula2 = Copula.PredictiveImplication, + match_reverse = False, + compound_common_id = CommonId(0, 1), + Connector1 = Connector.SequentialEvents, + is_belief_valid = True, + ) + + + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__deduction_sequence_replace__1_0, + LinkType1 = [ + LinkType.COMPOUND_STATEMENT, + LinkType.COMPOUND_CONDITION + ], + LinkType2 = [ + LinkType.COMPOUND_STATEMENT, + LinkType.COMPOUND_CONDITION + ], + has_common_id = True, + has_compound_common_id = True, + Copula1 = Copula.PredictiveImplication, + Copula2 = Copula.PredictiveImplication, + match_reverse = False, + compound_common_id = CommonId(1, 0), + Connector2 = Connector.SequentialEvents, + is_belief_valid = True, + ) + + diff --git a/pynars/NARS/RuleMap/Rules/NAL8.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL8.py similarity index 88% rename from pynars/NARS/RuleMap/Rules/NAL8.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL8.py index 8845a03..0277ccc 100644 --- a/pynars/NARS/RuleMap/Rules/NAL8.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL8.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink from pynars.utils.SparseLUT import SparseLUT from pynars import Global -from .add_rule import * +from ....RuleMap.add_rule import * def add_rules__NAL8(sparse_lut: SparseLUT, structure: OrderedDict): diff --git a/pynars/NARS/RuleMap/Rules/NAL9.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL9.py similarity index 94% rename from pynars/NARS/RuleMap/Rules/NAL9.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL9.py index 44c4f7a..aceaf2a 100644 --- a/pynars/NARS/RuleMap/Rules/NAL9.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/NAL9.py @@ -2,7 +2,7 @@ from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink from pynars.utils.SparseLUT import SparseLUT from pynars import Global -from .add_rule import * +from ....RuleMap.add_rule import * from pynars.NARS.MentalOperation import * def add_rules__NAL9(sparse_lut: SparseLUT=None, structure: OrderedDict=None): diff --git a/pynars/NARS/RuleMap/Rules/__init__.py b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/__init__.py similarity index 88% rename from pynars/NARS/RuleMap/Rules/__init__.py rename to pynars/NARS/InferenceEngine/GeneralEngine/Rules/__init__.py index 5946543..a248ddc 100644 --- a/pynars/NARS/RuleMap/Rules/__init__.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/Rules/__init__.py @@ -1,4 +1,3 @@ -from .add_rule import * from .NAL1 import * from .NAL2 import * from .NAL3 import * diff --git a/pynars/NARS/InferenceEngine/GeneralEngine/__init__.py b/pynars/NARS/InferenceEngine/GeneralEngine/__init__.py new file mode 100644 index 0000000..f5b03fd --- /dev/null +++ b/pynars/NARS/InferenceEngine/GeneralEngine/__init__.py @@ -0,0 +1 @@ +from .GeneralEngine import GeneralEngine \ No newline at end of file diff --git a/pynars/NARS/RuleMap/_extract_feature.py b/pynars/NARS/InferenceEngine/GeneralEngine/extract_feature.py similarity index 81% rename from pynars/NARS/RuleMap/_extract_feature.py rename to pynars/NARS/InferenceEngine/GeneralEngine/extract_feature.py index a02f8f7..7192f05 100644 --- a/pynars/NARS/RuleMap/_extract_feature.py +++ b/pynars/NARS/InferenceEngine/GeneralEngine/extract_feature.py @@ -31,6 +31,7 @@ ], defaults=[False, True, None, None, False, None, None, False, None, None, False, None, None, None, None]# False, False, False, None, None] ) + def _mirorr_feature(premise1: Union[Term, Compound, Statement], premise2: Union[Term, Compound, Statement]): feature = extract_feature(premise2, premise1) return Feature( @@ -51,27 +52,6 @@ def _mirorr_feature(premise1: Union[Term, Compound, Statement], premise2: Union[ feature.the_other1 ) -def _compound_has_common(term1: Union[Term, Compound, Statement], term2: Union[Term, Compound, Statement]): - if term1.is_compound: - return (term2 in term1.terms) or term1.has_common(term2) - elif term2.is_compound: - return (term1 in term2.terms) or term1.has_common(term2) - else: return False - -def _compound_at(term1: Union[Term, Compound, Statement], term2: Compound, compound_has_common: bool=None): - if term2.is_compound: - if not term1.is_compound: - if term2.connector is Connector.SequentialEvents: - return term2.terms[0] == term1 - else: - return term2.contains(term1) - else: - empty = True if len(term2.terms - term1.terms) == 0 else False - if term2.connector is Connector.SequentialEvents: - return (not empty) and term2.terms[:len(term1.terms)] == term1.terms - else: - return (not empty) and (compound_has_common if compound_has_common is not None else _compound_has_common(term1, term2)) - else: return False def extract_feature(premise1: Union[Term, Compound, Statement], premise2: Union[Term, Compound, Statement]) -> Feature: ''' @@ -455,77 +435,3 @@ def extract_feature(premise1: Union[Term, Compound, Statement], premise2: Union[ -def _at(compound: Union[Compound, Statement], term: Term): - ''' - To judge whether the `component` is in the `compound`. - - e.g. A@(&&,A,B), then return (True, 0); - B@(&&,A,B), then return (True, 1); - C@(&&,A,B), then return (False, None) - ''' - if compound.is_atom: - return (False, None) - else: - if compound.is_compound: - terms = compound - elif compound.is_statement: - terms = (compound.subject, compound.predicate) - else: raise "Invalid case." - - for i, component in enumerate(terms): - if component == term: - return (True, i) - else: - return (False, None) - - -def _common(premise1: Statement, premise2: Statement): - ''' - To judge whether the `premise1` and the `premise2` have common term. - - e.g. M>, P>, then return (True, 1, 0); - P>, M>, then return (True, 0, 1); - P>, S>, then return (True, 0, 0); - M>, M>, then return (True, 1, 1); - B>, A, then return (True, 0, 0) - B>, B, then return (True, 1, 0) - - C>>, C> - (&, B, C)>, (&, B, C) - (&, B, C, D)>, (&, B, C) - (|, B, C), C> |- B> - <(&, A, B)-->(|, C, D), <(&, A, B)-->D> |- <(&, A, B)-->C> - - Return: - has_common_id (bool), common_id_task (int), common_id_belief (int), match_reverse (bool) - ''' - if premise1.is_statement and premise2.is_statement: - if premise1.subject == premise2.predicate and premise1.predicate == premise2.subject: - return True, None, None, True - if premise1.subject == premise2.subject: - return True, 0, 0, False - elif premise1.subject == premise2.predicate: - return True, 0, 1, False - elif premise1.predicate == premise2.subject: - return True, 1, 0, False - elif premise1.predicate == premise2.predicate: - return True, 1, 1, False - else: - return False, None, None, False - elif premise1.is_statement and premise2.is_atom: - if premise1.subject == premise2: - return True, 0, 0, False - elif premise1.predicate == premise2: - return True, 1, 0, False - else: - return False, None, None, False - elif premise2.is_statement and premise1.is_atom: - if premise2.subject == premise1: - return True, 0, 0, False - elif premise2.predicate == premise1: - return True, 0, 1, False - else: - return False, None, None, False - else: - return False, None, None, False - diff --git a/pynars/NARS/InferenceEngine/TemporalEngine.py b/pynars/NARS/InferenceEngine/TemporalEngine.py deleted file mode 100644 index 3167ed1..0000000 --- a/pynars/NARS/InferenceEngine/TemporalEngine.py +++ /dev/null @@ -1,106 +0,0 @@ -from copy import copy -from typing import Union -from pynars.NAL.Functions.Tools import project_truth, revisible, truth_to_quality -from pynars.NARS.DataStructures._py.Buffer import Buffer -from pynars.Narsese._py.Budget import Budget -from pynars.Narsese._py.Copula import Copula -from pynars.Narsese._py.Evidence import Base -from pynars.Narsese._py.Statement import Statement -from pynars.Narsese._py.Term import Term -from ..DataStructures import Task, Belief, Concept, TaskLink, TermLink -from typing import Callable, List, Tuple -from ..RuleMap import RuleCallable, RuleMap_v2 -from pynars.NAL.Inference import local__revision -from pynars.Config import Config -from pynars import Global -from pynars.NAL.Inference import * -from .Engine import Engine - -class TemporalEngine(Engine): - '''''' - - # rule_map = RuleMap_v2() - - def __init__(self) -> None: - '''''' - super().__init__() - - - def step(self, task: Task, concept: Union[Concept, None], sequence_buffer: Buffer, operations_buffer: Buffer): - '''''' - tasks_derived = [] - - if not (task.is_judgement and task.is_event): - return tasks_derived - - tasks_derived.extend(self.inference_with_sequence(task, sequence_buffer)) - self.add_event(task, concept, sequence_buffer) - - tasks_derived.extend(self.inference_with_operations(task, operations_buffer)) - self.add_operation_feedback(task, operations_buffer) - - return tasks_derived - - - def inference_with_sequence(self, task_event: Task, sequence_buffer: Buffer): - ''' - inference with `self.sequence_buffer` - Ref: OpenNARS 3.0.4 TemporalInferenceControl.java line 85~104 - ''' - tasks_derived = [] - tasks_attempted = [] - for _ in range(Config.n_sequence_attempts): - task: Task = sequence_buffer.take(True) - if task is None: break - tasks_attempted.append(task) - if task.evidential_base.is_overlaped(task_event.evidential_base): - continue - - # temporal induction - # TODO: use SparseLUT to find the rules. - task1, task2 = (task_event, task) if task.stamp.t_occurrence > task_event.stamp.t_occurrence else (task, task_event) - - task = temporal__induction_implication(task1, task2, None, None) - tasks_derived.append(task) - if task2.term.is_statement and task2.term.copula in (Copula.ConcurrentImplication, Copula.PredictiveImplication, Copula.RetrospectiveImplication): - task = temporal__induction_composition(task1, task2, None, None) - else: - task = temporal__induction_composition(task2, task1, None, None) - tasks_derived.append(task) - # TODO: The current impication above is problematic. - - for task in tasks_attempted: - sequence_buffer.put_back(task) - - - - return tasks_derived - - - def inference_with_operations(self, task_event: Task, operations_buffer: Buffer): - ''' - inference with `self.operations_buffer` - Ref: OpenNARS 3.0.4 TemporalInferenceControl.java line 107~162 - ''' - tasks_derived = [] - - return tasks_derived - - - def add_event(self, task_event: Task, concept: Concept, sequence_buffer: Buffer): - ''' - add the event task to `self.sequence_buffer` and `self.operations_buffer` - Ref: OpenNARS 3.0.4 TemporalInferenceControl.java line 167~213 - ''' - q = truth_to_quality(task_event.truth) - p = max(q, concept.budget.priority) if concept is not None else q - d = 1.0/task_event.term.complexity - budget = Budget(p, d, q) - task = Task(task_event.sentence, budget) - sequence_buffer.put(task) - - def add_operation_feedback(self, task_event: Task, operations_buffer: Buffer): - '''''' - # Ref: OpenNARS 3.0.4 ProcessJudgement.java line 116~126, TemporalInferenceControl.java line 215~245 - if task_event.is_operation and not task_event.is_mental_operation: - operations_buffer.put(task_event) \ No newline at end of file diff --git a/pynars/NARS/InferenceEngine/TemporalEngine/Rules/NAL7.py b/pynars/NARS/InferenceEngine/TemporalEngine/Rules/NAL7.py new file mode 100644 index 0000000..906e23f --- /dev/null +++ b/pynars/NARS/InferenceEngine/TemporalEngine/Rules/NAL7.py @@ -0,0 +1,133 @@ +from collections import OrderedDict +from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink +from pynars.utils.SparseLUT import SparseLUT +from pynars import Global +from ....RuleMap.add_rule import * + + +def add_rules__NAL7(sparse_lut: SparseLUT, structure: OrderedDict): + '''''' + '''''' + add_rule(sparse_lut, structure, + [ + Interface_TemporalRules._temporal__induction_composition, + Interface_TemporalRules._temporal__induction_implication, + Interface_TemporalRules._temporal__induction_implication_prime, + Interface_TemporalRules._temporal__induction_equivalence, + ], + is_temporal_copula1 = False, + is_temporal_copula2 = False + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__induction_composition, + is_temporal_copula1 = False, + is_temporal_copula2 = True + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__induction_composition, + is_temporal_copula1 = True, + is_temporal_copula2 = False + ) + + '''''' + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__induction_implication, + is_temporal_copula1 = False, + is_temporal_copula2 = False + ) + add_rule(sparse_lut, structure, + Interface_TemporalRules._temporal__induction_implication_prime, + is_temporal_copula1 = False, + is_temporal_copula2 = False + ) + + '''''' + add_rule(sparse_lut, structure, + [ + Interface_TemporalRules._temporal__induction_predictieve_implication_composition, + Interface_TemporalRules._temporal__induction_predictive_implication_composition_inverse, + Interface_TemporalRules._temporal__induction_predictive_equivalance_composition + ], + is_temporal_copula1 = False, + is_temporal_copula2 = True, + copula2 = [ + Copula.PredictiveImplication, + Copula.ConcurrentImplication + ] + ) + add_rule(sparse_lut, structure, + [ + Interface_TemporalRules._temporal__induction_predictive_implication_composition_prime, + Interface_TemporalRules._temporal__induction_predictive_implication_composition_inverse_prime, + Interface_TemporalRules._temporal__induction_predictive_equivalance_composition_prime + ], + is_temporal_copula1 = True, + is_temporal_copula2 = False, + copula1 = [ + Copula.PredictiveImplication, + Copula.ConcurrentImplication + ] + ) + + '''''' + add_rule(sparse_lut, structure, + [ + Interface_TemporalRules._temporal__induction_retrospective_implication_composition, + Interface_TemporalRules._temporal__induction_retrospective_implication_composition_inverse, + Interface_TemporalRules._temporal__induction_retrospective_equivalance_composition + + ], + is_temporal_copula1 = False, + is_temporal_copula2 = True, + copula2 = Copula.RetrospectiveImplication + ) + add_rule(sparse_lut, structure, + [ + Interface_TemporalRules._temporal__induction_retrospective_implication_composition_prime, + Interface_TemporalRules._temporal__induction_retrospective_implication_composition_inverse_prime, + Interface_TemporalRules._temporal__induction_retrospective_equivalance_composition_prime + ], + is_temporal_copula1 = True, + is_temporal_copula2 = False, + copula1 = Copula.RetrospectiveImplication + ) + + # add_rule(sparse_lut, structure, + # Interface_TemporalRules._temporal__induction_predictive_implication_composition_inverse, + # is_temporal_copula1 = False, + # is_temporal_copula2 = True, + # coupla2 = [Copula.RetrospectiveImplication] + # ) + # add_rule(sparse_lut, structure, + # Interface_TemporalRules._temporal__induction_predictive_implication_composition_inverse_prime, + # is_temporal_copula1 = True, + # is_temporal_copula2 = False, + # coupla1 = [Copula.RetrospectiveImplication] + # ) + + + # add_rule(sparse_lut, structure, + # Interface_TemporalRules._temporal__induction_implication_composition, + # connector1 = [None, Connector.SequentialEvents, Connector.ParallelEvents], + # copula2 = Copula.PredictiveImplication + # ) + + # add_rule(sparse_lut, structure, + # [ + # Interface_TemporalRules._temporal__induction_implication, + # Interface_TemporalRules._temporal__induction_implication_prime + # ], + # is_temporal_copula1 = False, + # is_temporal_copula2 = False + # ) + # add_rule(sparse_lut, structure, + # [ + # Interface_TemporalRules._temporal__induction_implication, + # Interface_TemporalRules._temporal__induction_implication_prime, + # Interface_TemporalRules._temporal__induction_composition, + # ], + # is_temporal_copula1 = False, + # is_temporal_copula2 = False, + # is_temporal_connector1 = False, + # is_temporal_connector2 = False + # ) \ No newline at end of file diff --git a/pynars/NARS/InferenceEngine/TemporalEngine/Rules/__init__.py b/pynars/NARS/InferenceEngine/TemporalEngine/Rules/__init__.py new file mode 100644 index 0000000..82969a0 --- /dev/null +++ b/pynars/NARS/InferenceEngine/TemporalEngine/Rules/__init__.py @@ -0,0 +1 @@ +from .NAL7 import * \ No newline at end of file diff --git a/pynars/NARS/InferenceEngine/TemporalEngine/TemporalEngine.py b/pynars/NARS/InferenceEngine/TemporalEngine/TemporalEngine.py new file mode 100644 index 0000000..2e394d1 --- /dev/null +++ b/pynars/NARS/InferenceEngine/TemporalEngine/TemporalEngine.py @@ -0,0 +1,171 @@ +from copy import copy +from typing import Union + +from pynars.NAL.Functions.Tools import project_truth, revisible, truth_to_quality +from pynars.NARS.DataStructures._py.Buffer import Buffer +from pynars.NARS.DataStructures._py.Link import LinkType +from .Rules import * +from pynars.NARS.RuleMap.add_rule import CommonId +from pynars.Narsese._py.Budget import Budget +from pynars.Narsese._py.Connector import Connector +from pynars.Narsese._py.Copula import Copula +from pynars.Narsese._py.Evidence import Base +from pynars.Narsese._py.Statement import Statement +from pynars.Narsese._py.Term import Term +from ...DataStructures import Task, Belief, Concept, TaskLink, TermLink +from typing import Callable, List, Tuple +from ...RuleMap import RuleCallable, RuleMap +from pynars.NAL.Inference import local__revision +from pynars.Config import Config +from pynars import Global +from pynars.NAL.Inference import * +from ..Engine import Engine +from .extract_feature import extract_feature +from pathlib import Path + +class TemporalEngine(Engine): + '''''' + + rule_map = RuleMap(name='LUT_Tense', root_rules=Path(__file__).parent/'Rules') + + def __init__(self, build=True, add_rules={1,2,3,4,5,6,7,8,9}): + '''''' + super().__init__() + n_is_temporal_copula1 = 2 + n_is_temporal_copula2 = 2 + n_is_temporal_connector1 = 2 + n_is_temporal_connector2 = 2 + n_copula = len(Copula) + n_connector = len(Connector) + + self.rule_map.init_type( + ("is_temporal_copula1", bool, n_is_temporal_copula1), + ("is_temporal_copula2", bool, n_is_temporal_copula2), + ("is_temporal_connector1", bool, n_is_temporal_connector1), + ("is_temporal_connector2", bool, n_is_temporal_connector2), + ('copula1', Copula, n_copula), + ('copula2', Copula, n_copula), + ('connector1', Connector, n_connector), + ('connector2', Connector, n_connector), + + ) + + map = self.rule_map.map + structure = self.rule_map.structure + add_rules__NAL7(map, structure) if 7 in add_rules else None + + if build: self.build() + + @classmethod + def match(cls, task_event1: Task, task_event2: Task): + '''To verify whether the task and the belief can interact with each other''' + + is_valid = False + rules = cls.match_rule(task_event1, task_event2) + if rules is not None and len(rules) > 0: + is_valid = True + + return is_valid, rules + + @classmethod + def match_rule(cls, task_event1: Task, task_event2: Task): + ''' + Given two events, find the matched rules for one step inference. + ''' + term1 = task_event1.term + term2 = task_event2.term + feature = extract_feature(term1, term2) + indices = ( + int(feature.is_temporal_copula1), + int(feature.is_temporal_copula2), + int(feature.is_temporal_connector1), + int(feature.is_temporal_connector2), + int(term1.copula) if term1.is_statement else None, + int(term2.copula) if term2.is_statement else None, + int(term1.connector) if term1.is_compound else None, + int(term2.connector) if term2.is_compound else None + ) + rules: RuleCallable = cls.rule_map[indices] + return rules + + @staticmethod + def inference(task_event1: Task, task_event2: Task, rules: List[Callable[[Task, Task], List[Task]]]) -> List[Task]: + '''''' + tasks_derived = [rule(task_event1, task_event2) for rule in rules] + + return tasks_derived + + def step(self, task: Task, concept: Union[Concept, None], sequence_buffer: Buffer, operations_buffer: Buffer): + '''''' + tasks_derived_all = [] + + if not (task.is_judgement and task.is_external_event): + return tasks_derived_all + + tasks_derived = self.step_with_sequence(task, sequence_buffer) + self.add_event(task, concept, sequence_buffer) + tasks_derived_all.extend(tasks_derived) + + tasks_derived = self.step_with_operations(task, operations_buffer) + tasks_derived_all.extend(tasks_derived) + self.add_operation_feedback(task, operations_buffer) + + return tasks_derived_all + + + def step_with_sequence(self, task_event: Task, sequence_buffer: Buffer): + ''' + inference with `self.sequence_buffer` + Ref: OpenNARS 3.0.4 TemporalInferenceControl.java line 85~104 + ''' + tasks_derived = [] + tasks_attempted = [] + for _ in range(Config.n_sequence_attempts): + task: Task = sequence_buffer.take(True) + if task is None: break + tasks_attempted.append(task) + if task.evidential_base.is_overlaped(task_event.evidential_base): + continue + + + # temporal induction + # TODO: use SparseLUT to find the rules. + is_valid, rules = TemporalEngine.match(task_event, task) + if is_valid: + tasks_derived = self.inference(task_event, task, rules) + + for task in tasks_attempted: + sequence_buffer.put_back(task) + + + + return tasks_derived + + + def step_with_operations(self, task_event: Task, operations_buffer: Buffer): + ''' + inference with `self.operations_buffer` + Ref: OpenNARS 3.0.4 TemporalInferenceControl.java line 107~162 + ''' + tasks_derived = [] + + return tasks_derived + + + def add_event(self, task_event: Task, concept: Concept, sequence_buffer: Buffer): + ''' + add the event task to `self.sequence_buffer` and `self.operations_buffer` + Ref: OpenNARS 3.0.4 TemporalInferenceControl.java line 167~213 + ''' + q = truth_to_quality(task_event.truth) + p = max(q, concept.budget.priority) if concept is not None else q + d = 1.0/task_event.term.complexity + budget = Budget(p, d, q) + task = Task(task_event.sentence, budget) + sequence_buffer.put(task) + + def add_operation_feedback(self, task_event: Task, operations_buffer: Buffer): + '''''' + # Ref: OpenNARS 3.0.4 ProcessJudgement.java line 116~126, TemporalInferenceControl.java line 215~245 + if task_event.is_operation and not task_event.is_mental_operation: + operations_buffer.put(task_event) \ No newline at end of file diff --git a/pynars/NARS/InferenceEngine/TemporalEngine/__init__.py b/pynars/NARS/InferenceEngine/TemporalEngine/__init__.py new file mode 100644 index 0000000..6be8b4a --- /dev/null +++ b/pynars/NARS/InferenceEngine/TemporalEngine/__init__.py @@ -0,0 +1 @@ +from .TemporalEngine import TemporalEngine diff --git a/pynars/NARS/InferenceEngine/TemporalEngine/extract_feature.py b/pynars/NARS/InferenceEngine/TemporalEngine/extract_feature.py new file mode 100644 index 0000000..f0f39e6 --- /dev/null +++ b/pynars/NARS/InferenceEngine/TemporalEngine/extract_feature.py @@ -0,0 +1,45 @@ +from typing import Union +from collections import namedtuple + +from pynars.Narsese._py.Connector import Connector +from pynars.NAL.Inference import * +from pynars.Narsese import Statement, Term, Compound +from pynars.Narsese._py.Copula import Copula + +Feature = namedtuple( + 'Feature', + [ + 'is_temporal_copula1', + 'is_temporal_copula2', + 'is_temporal_connector1', + 'is_temporal_connector2' + ], + defaults=[None, None, None, None] +) + +def _mirorr_feature(premise1: Union[Term, Compound, Statement], premise2: Union[Term, Compound, Statement]): + feature = extract_feature(premise2, premise1) + return Feature( + feature.is_temporal_copula2, + feature.is_temporal_copula1, + feature.is_temporal_connector2, + feature.is_temporal_connector1 + ) + + +def extract_feature(premise1: Union[Term, Compound, Statement], premise2: Union[Term, Compound, Statement]) -> Feature: + ''' + It should be ensured that premise1 and premise2 aren't identical. + ''' + is_temporal_copula1 = premise1.is_statement and premise1.copula.is_temporal + is_temporal_copula2 = premise2.is_statement and premise2.copula.is_temporal + is_temporal_connector1 = premise1.is_compound and premise1.connector.is_temporal + is_temporal_connector2 = premise2.is_compound and premise2.connector.is_temporal + return Feature( + is_temporal_copula1=is_temporal_copula1, + is_temporal_copula2=is_temporal_copula2, + is_temporal_connector1=is_temporal_connector1, + is_temporal_connector2=is_temporal_connector2, + + ) + diff --git a/pynars/NARS/RuleMap/Interface/Interface_TemporalRules.py b/pynars/NARS/RuleMap/Interface/Interface_TemporalRules.py index cbc6a96..4e93973 100644 --- a/pynars/NARS/RuleMap/Interface/Interface_TemporalRules.py +++ b/pynars/NARS/RuleMap/Interface/Interface_TemporalRules.py @@ -3,6 +3,7 @@ from pynars.NAL.Inference import * from pynars.NAL.Theorems import * from pynars import Global +from pynars.Narsese._py.Copula import Copula def _temporal__deduction_sequence_eliminate__0(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): @@ -24,23 +25,111 @@ def _temporal__abduction__1_prime(task: Task, belief: Belief, tasklink: TaskLink '''{C. :|: <(&/, C, +100, S, ...) =/> P>.} |- P>. :!105:''' return temporal__abduction(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True) +def _temporal__deduction_sequence_replace__0_1(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''{<(&&, C, S, ...) ==> P>. P>.} |- P.''' + return temporal__deduction_sequence_replace(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False) -def _temporal__implication_induction(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): +def _temporal__deduction_sequence_replace__1_0(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''{ P>. <(&&, C, S, ...) ==> P>.} |- P.''' + return temporal__deduction_sequence_replace(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True) + + + +'''analogy''' +def _temporal__analogy__0_1(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + is_equivalence = belief.term.copula in (Copula.ConcurrentEquivalence, Copula.PredictiveEquivalence) + return temporal__analogy(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False if is_equivalence else True, inverse_copula=False if is_equivalence else True) + + +def _temporal__analogy__1_0(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + is_equivalence = belief.term.copula in (Copula.ConcurrentEquivalence, Copula.PredictiveEquivalence) + return temporal__analogy(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False if is_equivalence else True, inverse_copula=True if is_equivalence else False) + + +def _temporal__analogy__0_0(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + is_equivalence = belief.term.copula in (Copula.ConcurrentEquivalence, Copula.PredictiveEquivalence) + return temporal__analogy(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False if is_equivalence else True, inverse_copula=False) + + +def _temporal__analogy__1_1(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + is_equivalence = belief.term.copula in (Copula.ConcurrentEquivalence, Copula.PredictiveEquivalence) + return temporal__analogy(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False if is_equivalence else True, inverse_copula=True) + +'''Sequential induction''' +# TODO: the name of each rule may need to be modifed. +def _temporal__induction_implication(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_implication(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False) + + +def _temporal__induction_implication_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_implication(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True) + + +def _temporal__induction_equivalence(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_equivalence(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False) + + +def _temporal__induction_composition(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False) + +'''''' +def _temporal__induction_predictieve_implication_composition(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): '''''' - return temporal__implication_induction(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False) + return temporal__induction_predictive_implication_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False, inverse_copula=False) -def _temporal__implication_induction_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): +def _temporal__induction_predictive_implication_composition_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): '''''' - return temporal__implication_induction(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True) + return temporal__induction_predictive_implication_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True, inverse_copula=False) -def _temporal__composition_induction(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): +def _temporal__induction_predictive_implication_composition_inverse(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): '''''' - return temporal__composition_induction(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False) + return temporal__induction_predictive_implication_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False, inverse_copula=True) -def _temporal__composition_induction_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): +def _temporal__induction_predictive_implication_composition_inverse_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): '''''' - return temporal__composition_induction(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True) + return temporal__induction_predictive_implication_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True, inverse_copula=True) + +'''''' +def _temporal__induction_retrospective_implication_composition(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_retrospective_implication_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False, inverse_copula=False) + + +def _temporal__induction_retrospective_implication_composition_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_retrospective_implication_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True, inverse_copula=False) + + +def _temporal__induction_retrospective_implication_composition_inverse(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_retrospective_implication_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False, inverse_copula=True) + + +def _temporal__induction_retrospective_implication_composition_inverse_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_retrospective_implication_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True, inverse_copula=True) + + +def _temporal__induction_predictive_equivalance_composition(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_predictive_equivalance_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False, inverse_copula=False) + +def _temporal__induction_predictive_equivalance_composition_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_predictive_equivalance_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True, inverse_copula=False) + +def _temporal__induction_retrospective_equivalance_composition(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_retrospective_equivalance_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=False, inverse_copula=False) + +def _temporal__induction_retrospective_equivalance_composition_prime(task: Task, belief: Belief, tasklink: TaskLink=None, termlink: TermLink=None): + '''''' + return temporal__induction_retrospective_equivalance_composition(task, belief, (tasklink.budget if tasklink is not None else None), (termlink.budget if termlink is not None else None), inverse_premise=True, inverse_copula=False) diff --git a/pynars/NARS/RuleMap/RuleMap.py b/pynars/NARS/RuleMap/RuleMap.py new file mode 100644 index 0000000..91f0633 --- /dev/null +++ b/pynars/NARS/RuleMap/RuleMap.py @@ -0,0 +1,136 @@ +from operator import imod +import os +from pathlib import Path +from inspect import getmembers, isfunction +import importlib +import re +from typing import Any, Callable, Iterable, List, Tuple, Union +from typing_extensions import Protocol +from collections import OrderedDict + +from numpy import iterable, product + +from pynars.Config import Enable +from pynars.Narsese import Copula, Task +from pynars.Narsese import Connector, Statement, Belief, Term, Truth, Compound, Budget +from ..DataStructures import LinkType, TaskLink, TermLink +from pynars.NAL.Inference import * +from pynars.utils.SparseLUT import SparseLUT +from pynars.utils.tools import get_size + +from pynars.utils.Print import out_print, PrintType + +import time +from datetime import datetime +import pickle +import sty +# from ..InferenceEngine.GeneralEngine.extract_feature import extract_feature +from .add_rule import _compound_has_common, _compound_at +from pynars import Global + + +class RuleMap: + match_rule: Callable + def __init__(self, build=True, add_rules={1,2,3,4,5,6,7,8,9}, name: str='LUT', root_rules: str=None): + self.name = name + self.root_rules = root_rules + pass + + + def init_type(self, *slots: Tuple[object, str, int]): + ''' + slots (List[Tuple[object, str, int]]): each slot is filled in with the type, which is a int number, of an object. + ''' + self.structure = OrderedDict([(slot[0], tuple(slot[1:])) for slot in slots]) + shape = tuple([n_type for *_, n_type in slots]) + self.map = SparseLUT(shape) + pass + + + def build(self, clear=True): + name_cache = self.name + root_path = Path(__file__).parent + def check_update(): + if self.root_rules is None: return True + + cache_path = root_path/f'{name_cache}.pkl' + try: + if not cache_path.exists(): return True + # this_filepath = Path(__file__) + filepaths = Path(self.root_rules).glob("NAL*.py") + mtime_cache = datetime.fromtimestamp(cache_path.stat().st_mtime) + for filepath in filepaths: + mtime_this = datetime.fromtimestamp(filepath.stat().st_mtime) + if mtime_this > mtime_cache: + return True + return False + except: + if not cache_path.exists(): return True + else: return False + + if check_update(): + self.rebuild(root_path, clear) + else: + self.load(str(root_path)) + + # if Enable.debug: out_print(PrintType.INFO, f'The size of map: {get_size(self.map.lut)/1024/1024:.6f}MB') + + def load(self, root_path: str): + if Enable.debug: out_print(PrintType.INFO, f'Loading RuleMap <{self.name}.pkl>...') + t_start = time.time() + self.map.load(str(root_path), self.name) + t_end = time.time() + if Enable.debug: out_print(PrintType.INFO, f'Done. Time-cost: {t_end-t_start}s.') + + def rebuild(self, root_path: str, clear=True): + '''''' + if Enable.debug: out_print(PrintType.INFO, f'Building RuleMap <{self.name}.pkl>...') + t_start = time.time() + self.map.build(clear) + t_end = time.time() + if Enable.debug: out_print(PrintType.INFO, f'Done. Time-cost: {t_end-t_start}s.') + if Enable.debug: out_print(PrintType.INFO, f'Saving RuleMap...') + self.map.dump(str(root_path), self.name) + if Enable.debug: out_print(PrintType.INFO, f'Done.') + + + def draw(self, show_labels=True): + self.map.draw(show_labels) + + + def verify(self, task_link: TaskLink, term_link: TermLink, *args): + raise "Invalid function." + + + def diagnose(self, indices): + ''' + Given a `indices`, check whether a valid rule can be retrieved. + If not, return the index of the position where an error occurs. + Else, return None. + In each case, Prompt message is printed. + ''' + for i in range(1,len(indices)): + if self.map[indices[:i]] is None: + name_str, (name_type, _) = list(self.structure.items())[i] + print(f"{sty.fg.blue}Diagnose: {sty.fg.red}ERROR.\n {sty.fg.blue}{i}: {sty.ef.bold}{name_str}, {name_type}{sty.rs.all}") + + return i + print(f"{sty.fg.blue}Diagnose: {sty.fg.green}PASS.{sty.rs.all}") + return None + + + def __repr__(self) -> str: + '''print self.type_map''' + r = f"\n" + for key, item in self.structure.items(): + r += f" {key}, {item}\n" + return r + + def __getitem__(self, item: Iterable): + return self.map[tuple(item)] + + +if __name__ == '__main__': + root_path = Path(__file__).parent + rulemap = RuleMap(build=False) + rulemap.rebuild(root_path) diff --git a/pynars/NARS/RuleMap/Rules/NAL7.py b/pynars/NARS/RuleMap/Rules/NAL7.py deleted file mode 100644 index 34f91a4..0000000 --- a/pynars/NARS/RuleMap/Rules/NAL7.py +++ /dev/null @@ -1,675 +0,0 @@ -from collections import OrderedDict -from pynars.NARS.DataStructures import LinkType, TaskLink, TermLink -from pynars.utils.SparseLUT import SparseLUT -from pynars import Global -from .add_rule import * - - -def add_rules__NAL7(sparse_lut: SparseLUT, structure: OrderedDict): - '''''' - '''deduction''' - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__deduction__0_1, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, - Copula2 = Copula.RetrospectiveImplication, - match_reverse = False, - common_id = CommonId(0, 1) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__deduction__1_0, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, - Copula2 = Copula.RetrospectiveImplication, - match_reverse = False, - common_id = CommonId(1, 0) - ) - - '''exemplification''' - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__exemplification__0_1, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, - Copula2 = Copula.RetrospectiveImplication, - match_reverse = False, - common_id = CommonId(0, 1) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__exemplification__1_0, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, - Copula2 = Copula.RetrospectiveImplication, - match_reverse = False, - common_id = CommonId(1, 0) - ) - - '''induction''' - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__induction__0_0, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.PredictiveImplication, - Copula2 = Copula.RetrospectiveImplication, - match_reverse = False, - common_id = CommonId(0, 0) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__induction__0_0, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, - Copula2 = Copula.PredictiveImplication, - match_reverse = False, - common_id = CommonId(0, 0) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__induction__0_0_prime, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.PredictiveImplication, - Copula2 = Copula.RetrospectiveImplication, - match_reverse = False, - common_id = CommonId(0, 0) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__induction__0_0_prime, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, - Copula2 = Copula.PredictiveImplication, - match_reverse = False, - common_id = CommonId(0, 0) - ) - - '''abduction''' - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__abduction__1_1, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.PredictiveImplication, # =/> - Copula2 = Copula.RetrospectiveImplication, # =\> - match_reverse = False, - common_id = CommonId(1, 1) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__abduction__1_1, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, # =\> - Copula2 = Copula.PredictiveImplication, # =/> - match_reverse = False, - common_id = CommonId(1, 1) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__abduction__1_1_prime, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.PredictiveImplication, # =/> - Copula2 = Copula.RetrospectiveImplication, # =\> - match_reverse = False, - common_id = CommonId(1, 1) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__abduction__1_1_prime, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, # =\> - Copula2 = Copula.PredictiveImplication, # =/> - match_reverse = False, - common_id = CommonId(1, 1) - ) - - '''comparison''' - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__comparison__0_0, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.PredictiveImplication, # =/> - Copula2 = Copula.RetrospectiveImplication, # =\> - match_reverse = False, - common_id = CommonId(0, 0) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__comparison__0_0_prime, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, # =\> - Copula2 = Copula.PredictiveImplication, # =/> - match_reverse = False, - common_id = CommonId(0, 0) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__comparison__1_1, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.PredictiveImplication, # =/> - Copula2 = Copula.RetrospectiveImplication, # =\> - match_reverse = False, - common_id = CommonId(1, 1) - ) - - add_rule(sparse_lut, structure, - Interface_SyllogisticRules._syllogistic__comparison__1_1_prime, - LinkType1 = LinkType.COMPOUND_CONDITION, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - Copula1 = Copula.RetrospectiveImplication, # =\> - Copula2 = Copula.PredictiveImplication, # =/> - match_reverse = False, - common_id = CommonId(1, 1) - ) - - '''reversion?''' - - '''---------------''' - - - '''---------NAL 5---------''' - - '''conditianal rules''' - - '''deduction''' - add_rule(sparse_lut, structure, - Interface_ConditionalRules._conditional__deduction__0, - LinkType1 = LinkType.COMPOUND_CONDITION, - # LinkType2 = LinkType.COMPOUND_STATEMENT, - has_common_id = True, - Copula1 = Copula.PredictiveImplication, - # Copula2 = Copula.PredictiveImplication, - match_reverse = False, - common_id = CommonId(0), - has_at = True, - p2_at_p1=True - ) - - add_rule(sparse_lut, structure, - Interface_ConditionalRules._conditional__deduction__0_prime, - # LinkType1 = LinkType.COMPOUND_STATEMENT, - LinkType2 = LinkType.COMPOUND_CONDITION, - has_common_id = True, - # Copula1 = Copula.PredictiveImplication, - Copula2 = Copula.PredictiveImplication, - match_reverse = False, - common_id = CommonId(0), - has_at = True, - p1_at_p2=True - ) - # '''deduction (compound eliminate)''' - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__deduction_compound_eliminate__0, - # LinkType1 = LinkType.COMPOUND_STATEMENT, - # LinkType2 = LinkType.COMPOUND_STATEMENT, - # has_common_id = True, - # has_compound_at = True, - # Copula1 = Copula.PredictiveImplication, - # # Copula2 = Copula.PredictiveImplication, - # match_reverse = False, - # common_id = CommonId(0), - # Connector1 = Connector.Conjunction - # ) - - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__deduction_compound_eliminate__0_prime, - # LinkType1 = LinkType.COMPOUND_STATEMENT, - # LinkType2 = LinkType.COMPOUND_STATEMENT, - # has_common_id = True, - # has_compound_at = True, - # # Copula1 = Copula.PredictiveImplication, - # Copula2 = Copula.PredictiveImplication, - # match_reverse = False, - # common_id = CommonId(0), - # Connector2 = Connector.Conjunction - # ) - - # '''deduction (compound replace)''' - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__deduction_compound_replace__0_1, - # LinkType1 = [ - # LinkType.COMPOUND_STATEMENT, - # LinkType.COMPOUND_CONDITION - # ], - # LinkType2 = [ - # LinkType.COMPOUND_STATEMENT, - # LinkType.COMPOUND_CONDITION - # ], - # has_common_id = True, - # has_compound_common_id = True, - # Copula1 = Copula.Implication, - # Copula2 = Copula.Implication, - # match_reverse = False, - # compound_common_id = CommonId(0, 1), - # Connector1 = Connector.Conjunction - # ) - - - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__deduction_compound_replace__1_0, - # LinkType1 = [ - # LinkType.COMPOUND_STATEMENT, - # LinkType.COMPOUND_CONDITION - # ], - # LinkType2 = [ - # LinkType.COMPOUND_STATEMENT, - # LinkType.COMPOUND_CONDITION - # ], - # has_common_id = True, - # has_compound_common_id = True, - # Copula1 = Copula.Implication, - # Copula2 = Copula.Implication, - # match_reverse = False, - # compound_common_id = CommonId(1, 0), - # Connector2 = Connector.Conjunction - # ) - - '''abduction''' - add_rule(sparse_lut, structure, - Interface_TemporalRules._temporal__abduction__1, - LinkType1 = [ - LinkType.COMPOUND_CONDITION, - LinkType.COMPOUND_STATEMENT - ], - # LinkType2 = LinkType.COMPOUND_STATEMENT, - has_common_id = True, - Copula1 = [ - Copula.PredictiveImplication, - Copula.ConcurrentImplication, - Copula.RetrospectiveImplication - ], - # Copula2 = Copula.PredictiveImplication, - match_reverse = False, - common_id = CommonId(1), - has_at = True, - p2_at_p1=True - ) - - add_rule(sparse_lut, structure, - Interface_TemporalRules._temporal__abduction__1_prime, - # LinkType1 = LinkType.COMPOUND_STATEMENT, - LinkType2 = [ - LinkType.COMPOUND_CONDITION, - LinkType.COMPOUND_STATEMENT - ], - has_common_id = True, - # Copula1 = Copula.PredictiveImplication, - Copula2 = [ - Copula.PredictiveImplication, - Copula.ConcurrentImplication, - Copula.RetrospectiveImplication - ], - match_reverse = False, - common_id = CommonId(1), - has_at = True, - p1_at_p2=True - ) - - # '''abudction (compound eliminate)''' - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__abduction_compound_eliminate__1_1, - # LinkType1 = [ - # LinkType.COMPOUND_CONDITION, - # LinkType.COMPOUND_STATEMENT - # ], - # LinkType2 = [ - # LinkType.COMPOUND_CONDITION, - # LinkType.COMPOUND_STATEMENT - # ], - # has_common_id = True, - # Copula1 = Copula.Implication, - # Copula2 = Copula.Implication, - # match_reverse = False, - # common_id = CommonId(1, 1), - # the_other_compound_has_common = True, - # the_other_compound_p1_at_p2 = False, - # the_other_compound_p2_at_p1 = True, - # Connector1 = Connector.Conjunction, - # Connector2 = None - # ) - - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__abduction_compound_eliminate__1_1_prime, - # LinkType1 = [ - # LinkType.COMPOUND_CONDITION, - # LinkType.COMPOUND_STATEMENT - # ], - # LinkType2 = [ - # LinkType.COMPOUND_CONDITION, - # LinkType.COMPOUND_STATEMENT - # ], - # has_common_id = True, - # Copula1 = Copula.Implication, - # Copula2 = Copula.Implication, - # match_reverse = False, - # common_id = CommonId(1, 1), - # the_other_compound_has_common = True, - # the_other_compound_p1_at_p2 = True, - # the_other_compound_p2_at_p1 = False, - # Connector1 = None, - # Connector2 = Connector.Conjunction - # ) - - # add_rule(sparse_lut, structure, - # [ - # Interface_ConditionalRules._conditional__abduction_compound_eliminate2__1_1, - # Interface_ConditionalRules._conditional__abduction_compound_eliminate2__1_1_prime - # ], - # LinkType1 = [ - # LinkType.COMPOUND_CONDITION, - # LinkType.COMPOUND_STATEMENT - # ], - # LinkType2 = [ - # LinkType.COMPOUND_CONDITION, - # LinkType.COMPOUND_STATEMENT - # ], - # has_common_id = True, - # Copula1 = Copula.Implication, - # Copula2 = Copula.Implication, - # match_reverse = False, - # common_id = CommonId(1, 1), - # the_other_compound_has_common = True, - # the_other_compound_p1_at_p2 = True, - # the_other_compound_p2_at_p1 = True, - # Connector1 = Connector.Conjunction, - # Connector2 = Connector.Conjunction - # ) - - # '''induction (compound replace)''' - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__induction_compound_replace__0_0, - # LinkType1 = [ - # LinkType.COMPOUND_STATEMENT, - # LinkType.COMPOUND_CONDITION - # ], - # LinkType2 = [ - # LinkType.COMPOUND_STATEMENT, - # LinkType.COMPOUND_CONDITION - # ], - # has_common_id = True, - # has_compound_common_id = True, - # Copula1 = Copula.Implication, - # Copula2 = Copula.Implication, - # match_reverse = False, - # compound_common_id = CommonId(0, 0), - # Connector1 = Connector.Conjunction - # ) - - - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__induction_compound_replace__0_0_prime, - # LinkType1 = [ - # LinkType.COMPOUND_STATEMENT, - # LinkType.COMPOUND_CONDITION - # ], - # LinkType2 = [ - # LinkType.COMPOUND_STATEMENT, - # LinkType.COMPOUND_CONDITION - # ], - # has_common_id = True, - # has_compound_common_id = True, - # Copula1 = Copula.Implication, - # Copula2 = Copula.Implication, - # match_reverse = False, - # compound_common_id = CommonId(0, 0), - # Connector2 = Connector.Conjunction - # ) - - # '''analogy''' - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__analogy__0, - # # LinkType1 = LinkType.COMPOUND_CONDITION, - # LinkType2 = LinkType.COMPOUND_CONDITION, - # has_common_id = True, - # # Copula1 = Copula.Implication, - # Copula2 = Copula.Equivalence, - # match_reverse = False, - # common_id = CommonId(0), - # has_at = True, - # p1_at_p2=True - # ) - - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__analogy__0_prime, - # LinkType1 = LinkType.COMPOUND_CONDITION, - # # LinkType2 = LinkType.COMPOUND_CONDITION, - # has_common_id = True, - # Copula1 = Copula.Equivalence, - # # Copula2 = Copula.Equivalence, - # match_reverse = False, - # common_id = CommonId(0), - # has_at = True, - # p2_at_p1=True - # ) - - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__analogy__1, - # # LinkType1 = LinkType.COMPOUND_CONDITION, - # LinkType2 = LinkType.COMPOUND_CONDITION, - # has_common_id = True, - # # Copula1 = Copula.Implication, - # Copula2 = Copula.Equivalence, - # match_reverse = False, - # common_id = CommonId(1), - # has_at = True, - # p1_at_p2=True - # ) - - # add_rule(sparse_lut, structure, - # Interface_ConditionalRules._conditional__analogy__1_prime, - # LinkType1 = LinkType.COMPOUND_CONDITION, - # # LinkType2 = LinkType.COMPOUND_CONDITION, - # has_common_id = True, - # Copula1 = Copula.Equivalence, - # # Copula2 = Copula.Equivalence, - # match_reverse = False, - # common_id = CommonId(1), - # has_at = True, - # p2_at_p1=True - # ) - - # ''' - # Decompositional Theorems - # ''' - - # '''decompositional theorem 9''' - # add_rule(sparse_lut, structure, - # Interface_DecompositionalRules._decompositional__decomposition_theorem9, - # LinkType1 = LinkType.COMPOUND, - # LinkType2 = LinkType.COMPOUND_STATEMENT, - # Connector1 = Connector.Conjunction, - # p2_at_p1 = True, - # is_belief_valid = True - # ) - - # add_rule(sparse_lut, structure, - # Interface_DecompositionalRules._decompositional__decomposition_theorem9, - # LinkType1 = LinkType.SELF, - # LinkType2 = LinkType.COMPONENT, - # Connector1 = Connector.Conjunction, - # p2_at_p1 = True, - # is_belief_valid = True - # ) - - # add_rule(sparse_lut, structure, - # Interface_DecompositionalRules._decompositional__decomposition_theorem9_prime, - # LinkType1 = LinkType.COMPOUND_STATEMENT, - # LinkType2 = LinkType.COMPOUND, - # Connector2 = Connector.Conjunction, - # p1_at_p2 = True, - # is_belief_valid = True - # ) - - # add_rule(sparse_lut, structure, - # Interface_DecompositionalRules._decompositional__decomposition_theorem9_prime, - # LinkType1 = LinkType.SELF, - # LinkType2 = LinkType.COMPOUND, - # Connector2 = Connector.Conjunction, - # p1_at_p2 = True, - # is_belief_valid = True - # ) - - # '''decompositional theorem 10''' - # add_rule(sparse_lut, structure, - # Interface_DecompositionalRules._decompositional__decomposition_theorem10, - # LinkType1 = LinkType.COMPOUND, - # LinkType2 = LinkType.COMPOUND_STATEMENT, - # Connector1 = Connector.Disjunction, - # p2_at_p1 = True, - # is_belief_valid = True - # ) - - # add_rule(sparse_lut, structure, - # Interface_DecompositionalRules._decompositional__decomposition_theorem10, - # LinkType1 = LinkType.SELF, - # LinkType2 = LinkType.COMPONENT, - # Connector1 = Connector.Disjunction, - # p2_at_p1 = True, - # is_belief_valid = True - # ) - - # add_rule(sparse_lut, structure, - # Interface_DecompositionalRules._decompositional__decomposition_theorem10_prime, - # LinkType1 = LinkType.COMPOUND_STATEMENT, - # LinkType2 = LinkType.COMPOUND, - # Connector2 = Connector.Disjunction, - # p1_at_p2 = True, - # is_belief_valid = True - # ) - - # add_rule(sparse_lut, structure, - # Interface_DecompositionalRules._decompositional__decomposition_theorem10_prime, - # LinkType1 = LinkType.SELF, - # LinkType2 = LinkType.COMPOUND, - # Connector2 = Connector.Disjunction, - # p1_at_p2 = True, - # is_belief_valid = True - # ) - - - # ''' - # Implication Theorems - # ''' - # add_rule(sparse_lut, structure, - # Interface_CompositionalRules._structural__implication_theorem3, - # LinkType1 = [LinkType.COMPOUND, LinkType.SELF], - # # LinkType2 = LinkType.COMPOUND, - # Connector1 = Connector.Conjunction, - # p2_at_p1 = True, - # is_belief_valid = False - # ) - - # add_rule(sparse_lut, structure, - # Interface_CompositionalRules._structural__implication_theorem4, - # # LinkType1 = LinkType.COMPOUND, - # LinkType2 = LinkType.COMPOUND, - # Connector2 = Connector.Disjunction, - # p1_at_p2 = True, - # is_belief_valid = False - # ) - - # '''transform negation''' - # add_rule(sparse_lut, structure, - # Interface_TransformRules._transform__negation, - # LinkType1 = LinkType.SELF, - # LinkType2 = LinkType.COMPONENT, - # Connector1 = Connector.Negation, - # # p2_at_p1 = True, - # is_belief_valid = False - # ) - - # add_rule(sparse_lut, structure, - # Interface_TransformRules._transform__negation, - # LinkType1 = LinkType.COMPOUND, - # LinkType2 = LinkType.COMPOUND_STATEMENT, - # Connector1 = Connector.Negation, - # # p2_at_p1 = True, - # is_belief_valid = False - # ) - - # add_rule(sparse_lut, structure, - # Interface_TransformRules._transform__negation, - # LinkType1 = [LinkType.SELF, LinkType.COMPOUND_STATEMENT], - # LinkType2 = LinkType.COMPOUND, - # Connector2 = Connector.Negation, - # # p2_at_p1 = True, - # is_belief_valid = False - # ) - - # '''contraposition''' - # add_rule(sparse_lut, structure, - # Interface_TransformRules._transform__contraposition, - # LinkType1 = LinkType.COMPOUND_CONDITION, - # LinkType2 = LinkType.COMPONENT, - # Connector1 = Connector.Negation, - # has_compound_at = True, - # c2_at_c1 = True, - # is_belief_valid = False - # ) - # # TODO: other cases should be considered. - # # add_rule(sparse_lut, structure, - # # Interface_TransformRules._transform__contraposition, - # # LinkType1 = LinkType.COMPOUND_CONDITION, - # # LinkType2 = LinkType.COMPONENT, - # # Connector1 = Connector.Negation, - # # has_compound_common_id = True, - # # c2_at_c1 = True, - # # is_belief_valid = False - # # ) - - '''---------NAL 7---------''' - '''sequential conditional deduction (compound eliminate)''' - add_rule(sparse_lut, structure, - Interface_TemporalRules._temporal__deduction_sequence_eliminate__0, - LinkType1 = LinkType.COMPOUND_STATEMENT, - LinkType2 = LinkType.COMPOUND_STATEMENT, - has_common_id = True, - has_compound_at = True, - Copula1 = Copula.PredictiveImplication, - # Copula2 = Copula.PredictiveImplication, - match_reverse = False, - common_id = CommonId(0), - Connector1 = Connector.SequentialEvents, - is_belief_valid=True - ) - - add_rule(sparse_lut, structure, - Interface_TemporalRules._temporal__deduction_sequence_eliminate__0_prime, - LinkType1 = LinkType.COMPOUND_STATEMENT, - LinkType2 = LinkType.COMPOUND_STATEMENT, - has_common_id = True, - has_compound_at = True, - # Copula1 = Copula.PredictiveImplication, - Copula2 = Copula.PredictiveImplication, - match_reverse = False, - common_id = CommonId(0), - Connector2 = Connector.SequentialEvents, - is_belief_valid=True - ) - diff --git a/pynars/NARS/RuleMap/__init__.py b/pynars/NARS/RuleMap/__init__.py index dc76446..2c77d31 100644 --- a/pynars/NARS/RuleMap/__init__.py +++ b/pynars/NARS/RuleMap/__init__.py @@ -1,2 +1,2 @@ -# from .RuleMap_v1 import RuleMap as RuleMap_v1, RuleCallable -from .RuleMap_v2 import RuleMap as RuleMap_v2, RuleCallable \ No newline at end of file +from .RuleMap import RuleMap +from .add_rule import * \ No newline at end of file diff --git a/pynars/NARS/RuleMap/Rules/add_rule.py b/pynars/NARS/RuleMap/add_rule.py similarity index 53% rename from pynars/NARS/RuleMap/Rules/add_rule.py rename to pynars/NARS/RuleMap/add_rule.py index 5d1c4c3..78e36a4 100644 --- a/pynars/NARS/RuleMap/Rules/add_rule.py +++ b/pynars/NARS/RuleMap/add_rule.py @@ -18,8 +18,7 @@ from pynars.Narsese._py.Statement import Statement from pynars.Narsese._py.Term import Term from pynars.Narsese import Belief, Term, Truth, Compound, Budget -# from .RuleMap_v1 import RuleMap as RuleMap_v1, RuleCallable -from ...DataStructures import LinkType, TaskLink, TermLink +from ..DataStructures import LinkType, TaskLink, TermLink from pynars.NAL.Inference import * from pynars.utils.SparseLUT import SparseLUT from pynars.utils.tools import get_size @@ -30,7 +29,7 @@ from datetime import datetime import pickle import sty -from .._extract_feature import extract_feature, _compound_has_common, _compound_at +# from ._extract_feature import extract_feature, _compound_has_common, _compound_at from pynars import Global class RuleCallable(Protocol): @@ -78,6 +77,105 @@ def __int__(self): return self.first*2 + self.second if self.second is not None else self.first +def _compound_has_common(term1: Union[Term, Compound, Statement], term2: Union[Term, Compound, Statement]): + if term1.is_compound: + return (term2 in term1.terms) or term1.has_common(term2) + elif term2.is_compound: + return (term1 in term2.terms) or term1.has_common(term2) + else: return False + +def _compound_at(term1: Union[Term, Compound, Statement], term2: Compound, compound_has_common: bool=None): + if term2.is_compound: + if not term1.is_compound: + if term2.connector is Connector.SequentialEvents: + return term2.terms[0] == term1 + else: + return term2.contains(term1) + else: + empty = True if len(term2.terms - term1.terms) == 0 else False + if term2.connector is Connector.SequentialEvents: + return (not empty) and term2.terms[:len(term1.terms)] == term1.terms + else: + return (not empty) and (compound_has_common if compound_has_common is not None else _compound_has_common(term1, term2)) + else: return False + +def _at(compound: Union[Compound, Statement], term: Term): + ''' + To judge whether the `component` is in the `compound`. + + e.g. A@(&&,A,B), then return (True, 0); + B@(&&,A,B), then return (True, 1); + C@(&&,A,B), then return (False, None) + ''' + if compound.is_atom: + return (False, None) + else: + if compound.is_compound: + terms = compound + elif compound.is_statement: + terms = (compound.subject, compound.predicate) + else: raise "Invalid case." + + for i, component in enumerate(terms): + if component == term: + return (True, i) + else: + return (False, None) + + +def _common(premise1: Statement, premise2: Statement): + ''' + To judge whether the `premise1` and the `premise2` have common term. + + e.g. M>, P>, then return (True, 1, 0); + P>, M>, then return (True, 0, 1); + P>, S>, then return (True, 0, 0); + M>, M>, then return (True, 1, 1); + B>, A, then return (True, 0, 0) + B>, B, then return (True, 1, 0) + + C>>, C> + (&, B, C)>, (&, B, C) + (&, B, C, D)>, (&, B, C) + (|, B, C), C> |- B> + <(&, A, B)-->(|, C, D), <(&, A, B)-->D> |- <(&, A, B)-->C> + + Return: + has_common_id (bool), common_id_task (int), common_id_belief (int), match_reverse (bool) + ''' + if premise1.is_statement and premise2.is_statement: + if premise1.subject == premise2.predicate and premise1.predicate == premise2.subject: + return True, None, None, True + if premise1.subject == premise2.subject: + return True, 0, 0, False + elif premise1.subject == premise2.predicate: + return True, 0, 1, False + elif premise1.predicate == premise2.subject: + return True, 1, 0, False + elif premise1.predicate == premise2.predicate: + return True, 1, 1, False + else: + return False, None, None, False + elif premise1.is_statement and premise2.is_atom: + if premise1.subject == premise2: + return True, 0, 0, False + elif premise1.predicate == premise2: + return True, 1, 0, False + else: + return False, None, None, False + elif premise2.is_statement and premise1.is_atom: + if premise2.subject == premise1: + return True, 0, 0, False + elif premise2.predicate == premise1: + return True, 0, 1, False + else: + return False, None, None, False + else: + return False, None, None, False + + + + def add_rule(sparse_lut: SparseLUT, structure: OrderedDict, rules: List[RuleCallable],**kwargs): '''''' indices = [kwargs.get(key, None) for key in structure.keys()] diff --git a/pynars/NARS/__init__.py b/pynars/NARS/__init__.py index 91e36af..fbd6bf5 100644 --- a/pynars/NARS/__init__.py +++ b/pynars/NARS/__init__.py @@ -1 +1 @@ -from .Control import Reasoner_3_0_4 \ No newline at end of file +from .Control import Reasoner \ No newline at end of file diff --git a/pynars/Narsese/_py/Compound.py b/pynars/Narsese/_py/Compound.py index 230f4e5..90da712 100644 --- a/pynars/Narsese/_py/Compound.py +++ b/pynars/Narsese/_py/Compound.py @@ -6,9 +6,9 @@ from pynars.Config import Enable from pynars.Narsese._py.Interval import Interval from pynars.utils.IndexVar import IndexVar -from .Term import Term, TermType +from .Term import Term, TermType, place_holder from .Terms import Terms -from .Connector import Connector, place_holder +from .Connector import Connector from typing import Iterable, List, Type, Union from ordered_set import OrderedSet from typing import Set @@ -201,6 +201,9 @@ def prepocess_terms(self, connector_parent: Connector, terms: Iterable[Union[Typ # otherwise, return `connector_parent` as the connector. return connector_parent, Terms(terms, is_commutative=True, is_input=is_input) else: + # e.g. (&/, (&/, A, B), (&|, C, D), E) will be converted to (&/, A, B, (&|, C, D), E) + terms = (term2 for term1 in (((term0 for term0 in term.terms) if term.is_compound and (term.connector is connector_parent) else (term,))for term in terms) for term2 in term1) + return connector_parent, Terms(terms, is_commutative=False, is_input=is_input) diff --git a/pynars/Narsese/_py/Connector.py b/pynars/Narsese/_py/Connector.py index 8459f5e..18232fa 100644 --- a/pynars/Narsese/_py/Connector.py +++ b/pynars/Narsese/_py/Connector.py @@ -1,6 +1,6 @@ # from enum import Enum from pynars.utils.IdEnum import IdEnum -from .Term import Term +# from .Term import Term class Connector(IdEnum): Conjunction = "&&" @@ -59,6 +59,10 @@ def is_multiple_only(self): Connector.ExtensionalImage ) + @property + def is_temporal(self): + return self in (Connector.SequentialEvents, Connector.ParallelEvents) + def check_valid(self, len_terms: int): if self.is_single_only: return len_terms == 1 elif self.is_double_only: return len_terms == 2 @@ -77,4 +81,4 @@ def check_valid(self, len_terms: int): # Connector.ExtensionalSet # ) -place_holder = Term('_', True) \ No newline at end of file +# place_holder = Term('_', True) \ No newline at end of file diff --git a/pynars/Narsese/_py/Copula.py b/pynars/Narsese/_py/Copula.py index 84e4449..1042e97 100644 --- a/pynars/Narsese/_py/Copula.py +++ b/pynars/Narsese/_py/Copula.py @@ -32,6 +32,9 @@ def is_higher_order(self): ) @property + def is_temporal(self): + return self in (Copula.ConcurrentEquivalence, Copula.PredictiveEquivalence, Copula.ConcurrentImplication, Copula.PredictiveImplication, Copula.RetrospectiveImplication) + def symmetrize(self): if self is Copula.Inheritance: return Copula.Similarity @@ -43,6 +46,14 @@ def symmetrize(self): return Copula.PredictiveEquivalence else: raise "Invalid case." + + def inverse(self): + if self is Copula.PredictiveImplication: + return Copula.RetrospectiveImplication + elif self is Copula.RetrospectiveImplication: + return Copula.PredictiveImplication + else: + return self @property diff --git a/pynars/Narsese/_py/Interval.py b/pynars/Narsese/_py/Interval.py index 93f5d69..3b48b93 100644 --- a/pynars/Narsese/_py/Interval.py +++ b/pynars/Narsese/_py/Interval.py @@ -1,3 +1,4 @@ +from typing import Type from .Term import Term @@ -11,4 +12,7 @@ def __repr__(self) -> str: return f'' def __int__(self) -> int: - return self.interval \ No newline at end of file + return self.interval + + def __add__(self, o: Type['Interval']): + return Interval(int(self)+int(o)) \ No newline at end of file diff --git a/pynars/Narsese/_py/Sentence.py b/pynars/Narsese/_py/Sentence.py index b4890fa..4629bf6 100644 --- a/pynars/Narsese/_py/Sentence.py +++ b/pynars/Narsese/_py/Sentence.py @@ -35,7 +35,7 @@ def is_quest(self): class Stamp: - def __init__(self, t_creation: int, t_occurrence: int, t_put: int, evidential_base: Type['Base']) -> None: + def __init__(self, t_creation: int, t_occurrence: int, t_put: int, evidential_base: Type['Base'], is_external: bool=True) -> None: ''' Args: t_creation(int): creation time of the stamp @@ -46,11 +46,12 @@ def __init__(self, t_creation: int, t_occurrence: int, t_put: int, evidential_ba self.t_occurrence = t_occurrence self.t_put = t_put self.evidential_base: Type['Base'] = evidential_base + self.is_external = is_external # whether a sentence is from the external world or the internal world. Only those sentences derived from Mental Operations are internal. @property def tense(self): - return Tense.Eternal if self.t_occurrence is None else Tense.Future if self.t_occurrence > Global.time+Config.temporal_duration else Tense.Past if self.t_occurrence < Global.time-Config.temporal_duration else Tense.Present + return Tense.Eternal if self.t_occurrence is None else Tense.Future if self.t_occurrence >= Global.time+Config.temporal_duration else Tense.Past if self.t_occurrence <= Global.time-Config.temporal_duration else Tense.Present @property def is_eternal(self): @@ -135,11 +136,16 @@ def is_quest(self) -> bool: @property def is_eternal(self) -> bool: - return self.tense == Tense.Eternal + return self.stamp.is_eternal @property def is_event(self) -> bool: - return self.tense != Tense.Eternal + return not self.stamp.is_eternal + + @property + def is_external_event(self) -> bool: + return not self.is_eternal and self.stamp.is_external + class Judgement(Sentence): diff --git a/pynars/Narsese/_py/Task.py b/pynars/Narsese/_py/Task.py index 24a6a84..7ed911d 100644 --- a/pynars/Narsese/_py/Task.py +++ b/pynars/Narsese/_py/Task.py @@ -81,6 +81,10 @@ def is_eternal(self) -> bool: def is_event(self) -> bool: return self.sentence.is_event + @property + def is_external_event(self) -> bool: + return self.sentence.is_external_event + @property def is_operation(self) -> bool: return self.term.is_operation diff --git a/pynars/Narsese/_py/Term.py b/pynars/Narsese/_py/Term.py index ea68331..0691ea0 100644 --- a/pynars/Narsese/_py/Term.py +++ b/pynars/Narsese/_py/Term.py @@ -1,3 +1,4 @@ +from pynars.Narsese._py.Connector import Connector from .Copula import Copula from pynars.Config import Enable from typing import Iterable, List, Set, Type @@ -17,6 +18,7 @@ class Term: type = TermType.ATOM copula: Copula = None + connector: Connector = None _complexity: float = 1.0 # The complexity of the term. Read only. has_var: bool = False # Whether the term contains variable(s). has_ivar: bool = False # Whether the term contains independent variable(s). @@ -201,4 +203,6 @@ def handle_index_var(self, terms: Iterable['Term'], is_input: bool): def clone(self): # clone = copy(self) return self - \ No newline at end of file + + +place_holder = Term('_', True) \ No newline at end of file diff --git a/pynars/__init__.py b/pynars/__init__.py index 1475a38..b04244e 100644 --- a/pynars/__init__.py +++ b/pynars/__init__.py @@ -1,4 +1,4 @@ -__version__ = 'v0.0.1 pre-alpha' +__version__ = 'v0.0.2 pre-alpha' version = __version__.split(' ')[0].lstrip('v') print(f'PyNARS version {__version__}') \ No newline at end of file diff --git a/pynars/utils/SparseLUT/.gitignore b/pynars/utils/SparseLUT/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/pynars/utils/SparseLUT/branch_list.cp37-win_amd64.pyd b/pynars/utils/SparseLUT/branch_list.cp37-win_amd64.pyd new file mode 100644 index 0000000..bbbb2ac Binary files /dev/null and b/pynars/utils/SparseLUT/branch_list.cp37-win_amd64.pyd differ diff --git a/pynars/utils/SparseLUT/sparse_lut.cp37-win_amd64.pyd b/pynars/utils/SparseLUT/sparse_lut.cp37-win_amd64.pyd new file mode 100644 index 0000000..caba7ad Binary files /dev/null and b/pynars/utils/SparseLUT/sparse_lut.cp37-win_amd64.pyd differ diff --git a/pynars/utils/SparseLUT/sparse_lut.pyi b/pynars/utils/SparseLUT/sparse_lut.pyi index 3b536aa..84afef5 100644 --- a/pynars/utils/SparseLUT/sparse_lut.pyi +++ b/pynars/utils/SparseLUT/sparse_lut.pyi @@ -11,8 +11,8 @@ class SparseLUT: def add(self, indices: Union[list, tuple], value): ... def build(self, clear: bool = ...) -> None: ... def clear(self) -> None: ... - def dump(self, root_path: str): ... - def load(self, root_path: str): ... + def dump(self, root_path: str, name_cache: str = ...): ... + def load(self, root_path: str, name_cache: str = ...): ... def draw(self, show_labels: bool = ...) -> None: ... def __setitem__(self, indices: tuple, value): ... def get(self, indices: tuple): ...