diff --git a/Tests/test_NAL/test_NAL7.py b/Tests/test_NAL/test_NAL7.py index 4c6b80b..4fb31fc 100644 --- a/Tests/test_NAL/test_NAL7.py +++ b/Tests/test_NAL/test_NAL7.py @@ -278,7 +278,7 @@ def test_inference_on_tense_0(self): tasks_derived = process_two_premises( '<<(*,John,key_101) --> hold> =/> <(*,John,room_101) --> enter>>. %1.00;0.90%', '<(*,John,key_101) --> hold>. :|: %1.00;0.90%', - 20 + 10 ) self.assertTrue( output_contains(tasks_derived, '<(*,John,room_101) --> enter>. :!5: %1.00;0.81%') @@ -301,8 +301,8 @@ def test_inference_on_tense_1(self): ''outputMustContain('<(*,John,key_101) --> hold>. :!-10: %1.00;0.45%') ''' tasks_derived = process_two_premises( - '<(*,John,room_101) --> enter>. :\: %1.00;0.90%', '<<(*,John,key_101) --> hold> =/> <(*,John,room_101) --> enter>>. %1.00;0.90%', + '<(*,John,room_101) --> enter>. :\: %1.00;0.90%', 10 ) @@ -329,7 +329,7 @@ def test_inference_on_tense_2(self): tasks_derived = process_two_premises( '<<(*,John,key_101) --> hold> =/> <(*,John,room_101) --> enter>>. %1.00;0.90%', '<(*,John,room_101) --> enter>. :\: %1.00;0.90%', - 30 + 10 ) self.assertTrue( @@ -370,6 +370,7 @@ def test_induction_on_tense_0_0(self): None, 6 ) + Global.time = 6 tasks_derived.extend(process_two_premises( ' (/,enter,_,room_101)>. :|:', None, diff --git a/Tests/utils_for_test.py b/Tests/utils_for_test.py index 8e18563..018c82f 100644 --- a/Tests/utils_for_test.py +++ b/Tests/utils_for_test.py @@ -13,6 +13,7 @@ from pynars.NAL.MentalOperation import execute from pynars.Narsese import Sentence, Judgement, Quest, Question, Goal from pynars.Config import Config, Enable +from pynars import Global nars = Reasoner(100, 100) engine: GeneralEngine = nars.inference @@ -41,6 +42,10 @@ def process_two_premises(premise1: str, premise2: str, n_cycle: int = 0) -> List if answers_quest is not None: tasks_all_cycles.extend(answers_quest) + # reset time to correctly reflect tense + # ignoring cycle times + Global.time = 0 + return [t for t in tasks_all_cycles if t is not None] 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]]: diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index c124a2a..0514d47 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -9,7 +9,7 @@ from pynars.NARS.InferenceEngine import TemporalEngine # from pynars.NARS.Operation import Interface_Awareness from pynars.Narsese._py.Budget import Budget -from pynars.Narsese._py.Sentence import Judgement, Stamp +from pynars.Narsese._py.Sentence import Judgement, Stamp, Tense from pynars.Narsese._py.Statement import Statement from pynars.Narsese._py.Task import Belief from pynars.Narsese import Copula @@ -384,7 +384,7 @@ def inference_step(self, concept: Concept): results = [] - theorems_per_cycle = 5 + theorems_per_cycle = 10 # t0 = time() theorems = [] @@ -486,6 +486,16 @@ def inference_step(self, concept: Concept): and task.is_judgement: # TODO: handle other cases Global.States.record_premises(task, belief) + + # t0 = time() + + results = [] + + # COMPOSITIONAL + res, cached = self.inference.inference_compositional(task.sentence, belief.sentence) + + if not cached: + results.extend(res) # Temporal Projection and Eternalization if belief is not None: @@ -495,14 +505,8 @@ def inference_step(self, concept: Concept): belief = belief.eternalize(truth_belief) # beleif_eternalized = belief # TODO: should it be added into the `tasks_derived`? - # t0 = time() - - results = [] - + # SYLLOGISTIC res, cached = self.inference.inference(task.sentence, belief.sentence, concept.term) - - if not cached: - results.extend(res) # t1 = time() - t0 + 1e-6 # add epsilon to avoid division by 0 # print('syllogistic', 1//t1) @@ -517,7 +521,6 @@ def inference_step(self, concept: Concept): # t0 = time() - res, cached = self.inference.inference_compositional(task.sentence, belief.sentence) # t1 = time() - t0 # print("inf comp:", 1 // t1, "per second") @@ -531,11 +534,7 @@ def inference_step(self, concept: Concept): # print(">>>", results) for term, truth in results: - stamp_task: Stamp = task.stamp - stamp_belief: Stamp = belief.stamp - stamp = Stamp_merge(stamp_task, stamp_belief) - # TODO: calculate budget budget = Budget_forward(truth, task_link.budget, term_link_valid.budget) # Add temporal dimension @@ -604,9 +603,33 @@ def inference_step(self, concept: Concept): conclusion = conclusion.retrospective() + # calculate new stamp + stamp_task: Stamp = task.stamp + stamp_belief: Stamp = belief.stamp + + # TODO: how to correctly determine order? + order_mark = None + whole = part = None + + if task.sentence.term.copula and task.sentence.term.copula == Copula.PredictiveImplication: + whole = task + part = belief + if belief.sentence.term.copula and belief.sentence.term.copula == Copula.PredictiveImplication: + whole = belief + part = task + + if part and whole: + if part.term == whole.sentence.term.subject: + order_mark = Copula.PredictiveImplication + if part.term == whole.sentence.term.predicate: + order_mark = Copula.RetrospectiveImplication + + stamp = Stamp_merge(stamp_task, stamp_belief, order_mark) + sentence_derived = Judgement(conclusion, stamp, truth) - + # print(stamp.tense == sentence_derived.stamp.tense) task_derived = Task(sentence_derived, budget) + # print(task_derived.sentence.tense, task_derived) # normalize the variable indices task_derived.term._normalize_variables() tasks_derived.append(task_derived) diff --git a/pynars/NARS/InferenceEngine/KanrenEngine/KanrenEngine.py b/pynars/NARS/InferenceEngine/KanrenEngine/KanrenEngine.py index cdd1c07..73edd50 100644 --- a/pynars/NARS/InferenceEngine/KanrenEngine/KanrenEngine.py +++ b/pynars/NARS/InferenceEngine/KanrenEngine/KanrenEngine.py @@ -242,12 +242,14 @@ def inference_compositional(self, t1: Sentence, t2: Sentence): tr1, tr2 = (t1.truth, t2.truth) truth = truth_functions[r](tr1, tr2) - results.append(((res[0], r), truth)) + conclusion = self.determine_order(t1, t2, res[0]) + + results.append(((conclusion, r), truth)) # variable introduction - prefix = '$' if res[0].is_statement else '#' + prefix = '$' if conclusion.is_statement else '#' substitution = {logic(c, True, var_intro=True): var(prefix=prefix) for c in common} - reified = reify(logic(res[0], True, var_intro=True), substitution) + reified = reify(logic(conclusion, True, var_intro=True), substitution) conclusion = term(reified) @@ -255,6 +257,19 @@ def inference_compositional(self, t1: Sentence, t2: Sentence): return results + def determine_order(self, t1: Sentence, t2: Sentence, conclusion: Term): + # TODO: add .temporal() functions to Compound + # remove this condition when done + if type(conclusion) is Statement: + if t1.is_event and t2.is_event: + diff = t1.stamp.t_occurrence - t2.stamp.t_occurrence + if diff == 0: + conclusion = conclusion.concurrent() + if diff > 0: + conclusion = conclusion.predictive() + if diff < 0: + conclusion = conclusion.retrospective() + return conclusion diff --git a/pynars/Narsese/_py/Sentence.py b/pynars/Narsese/_py/Sentence.py index 979fc8c..6b169a0 100644 --- a/pynars/Narsese/_py/Sentence.py +++ b/pynars/Narsese/_py/Sentence.py @@ -176,7 +176,15 @@ def __str__(self) -> str: def repr(self,is_input=False): - return f'{self.term.repr()}{self.punct.value}{(" " + str(self.tense.value)) if self.tense != Tense.Eternal else ""} {self.truth}' + interval = "" + if self.tense != Tense.Eternal: + if self.tense == Tense.Present: + interval = str(self.tense.value) + if self.tense == Tense.Future: + interval = f':!{self.stamp.t_occurrence}:' + if self.tense == Tense.Past: + interval = f':!-{self.stamp.t_occurrence}:' + return f'{self.term.repr()}{self.punct.value} {interval} {self.truth}' class Goal(Sentence):