From 04c16e0b1b3d8e50d089683fcdd8c5e2290677f5 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Tue, 16 Jan 2024 18:03:48 -0500 Subject: [PATCH 1/7] Add methods to update Budget of Concept --- pynars/Config.py | 7 +++++++ pynars/NARS/DataStructures/_py/Concept.py | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/pynars/Config.py b/pynars/Config.py index 22cb8f78..96fc0ae8 100644 --- a/pynars/Config.py +++ b/pynars/Config.py @@ -71,6 +71,13 @@ class Config: rate_discount_p_internal_exp = 0.1 rate_discount_d_internal_exp = 0.1 + # parameters for updating the Budget of Concept. + # Lower values means it is harder to change the budget, higher values means it is easier to change the budget + concept_update_priority_weight = 0.1 + concept_update_durability_weight = 0.1 + concept_update_quality_weight = 0.1 + + # temporal_duration = 5 n_sequence_attempts = 10 n_op_condition_attempts = 10 diff --git a/pynars/NARS/DataStructures/_py/Concept.py b/pynars/NARS/DataStructures/_py/Concept.py index 05dc1051..5a147f0d 100644 --- a/pynars/NARS/DataStructures/_py/Concept.py +++ b/pynars/NARS/DataStructures/_py/Concept.py @@ -138,6 +138,19 @@ def accept(self, task: Task, concepts: Bag=None, conceptualize: bool=True): if concept is None: return # The memroy is full, and the concept fails to get into the memory. self._build_task_links(concepts, task) self._build_term_links(concepts, task, budget) + + + def update_priority(self, p): + self.budget.priority = (Config.concept_update_priority_weight * p + + (1-Config.concept_update_priority_weight)*self.budget.priority) + + def update_durability(self, d): + self.budget.durability = (Config.concept_update_durability_weight * d + + (1-Config.concept_update_durability_weight)*self.budget.durability) + + def update_quality(self, q): + self.budget.quality = (Config.concept_update_quality_weight * q + + (1-Config.concept_update_quality_weight)*self.budget.quality) def _build_task_links(self, concepts: Bag, task: Task): '''''' From 7059b6f7a625416006a8a269bb3ff3f774ef8395 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:33:17 -0500 Subject: [PATCH 2/7] #67 Update the Concept's Quality with the Revised Belief's Sharpness whenever a judgment is accepted --- pynars/NARS/DataStructures/_py/Memory.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pynars/NARS/DataStructures/_py/Memory.py b/pynars/NARS/DataStructures/_py/Memory.py index 32d87b1d..9fd125c4 100644 --- a/pynars/NARS/DataStructures/_py/Memory.py +++ b/pynars/NARS/DataStructures/_py/Memory.py @@ -86,6 +86,9 @@ def accept(self, task: Task): # Build the concepts corresponding to the terms of those components within the task. concept.accept(task, self.concepts, conceptualize=False) + + + if Enable.temporal_reasoning or Enable.operation: # if (!task.sentence.isEternal() && !(task.sentence.term instanceof Operation)) { # globalBuffer.eventInference(task, cont, false); //can be triggered by Buffer itself in the future @@ -140,6 +143,9 @@ def _accept_judgement(self, task: Task, concept: Concept): _, goal_answer = self._solve_goal(task_goal, concept, None, task) if goal_answer is not None: answers[Goal] = [goal_answer] + # Modify the concept's Budget using the belief + if belief_revised is not None: concept.update_quality(belief_revised.sharpness) + return belief_revised, answers def _accept_question(self, task: Task, concept: Concept): From acbb00dbec161a6db0f114769916814aef6fe5a2 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:36:47 -0500 Subject: [PATCH 3/7] #68 #71 use links to update the concept budget --- pynars/Config.py | 1 - pynars/NARS/DataStructures/_py/Concept.py | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pynars/Config.py b/pynars/Config.py index 96fc0ae8..24679f03 100644 --- a/pynars/Config.py +++ b/pynars/Config.py @@ -73,7 +73,6 @@ class Config: # parameters for updating the Budget of Concept. # Lower values means it is harder to change the budget, higher values means it is easier to change the budget - concept_update_priority_weight = 0.1 concept_update_durability_weight = 0.1 concept_update_quality_weight = 0.1 diff --git a/pynars/NARS/DataStructures/_py/Concept.py b/pynars/NARS/DataStructures/_py/Concept.py index 5a147f0d..4c2fba45 100644 --- a/pynars/NARS/DataStructures/_py/Concept.py +++ b/pynars/NARS/DataStructures/_py/Concept.py @@ -141,8 +141,7 @@ def accept(self, task: Task, concepts: Bag=None, conceptualize: bool=True): def update_priority(self, p): - self.budget.priority = (Config.concept_update_priority_weight * p - + (1-Config.concept_update_priority_weight)*self.budget.priority) + self.budget.priority = Or(self.budget.priority, p) def update_durability(self, d): self.budget.durability = (Config.concept_update_durability_weight * d @@ -202,10 +201,16 @@ def _build_term_links(self, concepts: Bag, task: Task, budget: Budget): def _insert_task_link(self, task_link: TaskLink): self.task_links.put(task_link) + # update the concept's budget using the link's budget + self.update_priority(task_link.budget.priority) + self.update_durability(task_link.budget.durability) # TODO: more handling. see OpenNARS 3.1.0 Concept.java line 318~366. def _insert_term_link(self, term_link: TermLink): self.term_links.put(term_link) + # update the concept's budget using the link's budget + self.update_priority(term_link.budget.priority) + self.update_durability(term_link.budget.durability) # TODO: more handling. see OpenNARS 3.1.0 Concept.java line 318~366. @classmethod From 0fce5be0da4223aef33559964e7031130d212f62 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:46:54 -0500 Subject: [PATCH 4/7] remove excessive whitespace --- pynars/Config.py | 2 +- pynars/NARS/DataStructures/_py/Concept.py | 1 - pynars/NARS/DataStructures/_py/Memory.py | 3 --- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/pynars/Config.py b/pynars/Config.py index 24679f03..93ac5a44 100644 --- a/pynars/Config.py +++ b/pynars/Config.py @@ -76,7 +76,7 @@ class Config: concept_update_durability_weight = 0.1 concept_update_quality_weight = 0.1 - # + # temporal parameters temporal_duration = 5 n_sequence_attempts = 10 n_op_condition_attempts = 10 diff --git a/pynars/NARS/DataStructures/_py/Concept.py b/pynars/NARS/DataStructures/_py/Concept.py index 4c2fba45..b1eac474 100644 --- a/pynars/NARS/DataStructures/_py/Concept.py +++ b/pynars/NARS/DataStructures/_py/Concept.py @@ -139,7 +139,6 @@ def accept(self, task: Task, concepts: Bag=None, conceptualize: bool=True): self._build_task_links(concepts, task) self._build_term_links(concepts, task, budget) - def update_priority(self, p): self.budget.priority = Or(self.budget.priority, p) diff --git a/pynars/NARS/DataStructures/_py/Memory.py b/pynars/NARS/DataStructures/_py/Memory.py index 9fd125c4..343b3e80 100644 --- a/pynars/NARS/DataStructures/_py/Memory.py +++ b/pynars/NARS/DataStructures/_py/Memory.py @@ -86,9 +86,6 @@ def accept(self, task: Task): # Build the concepts corresponding to the terms of those components within the task. concept.accept(task, self.concepts, conceptualize=False) - - - if Enable.temporal_reasoning or Enable.operation: # if (!task.sentence.isEternal() && !(task.sentence.term instanceof Operation)) { # globalBuffer.eventInference(task, cont, false); //can be triggered by Buffer itself in the future From 58a68fb2fc437a84ee27c9b7586fb1fc3abf6432 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Thu, 18 Jan 2024 03:46:48 -0500 Subject: [PATCH 5/7] Remove and replace Concept in Bag to properly change its level based on its updated budget --- pynars/NARS/DataStructures/_py/Memory.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pynars/NARS/DataStructures/_py/Memory.py b/pynars/NARS/DataStructures/_py/Memory.py index 343b3e80..46b0e673 100644 --- a/pynars/NARS/DataStructures/_py/Memory.py +++ b/pynars/NARS/DataStructures/_py/Memory.py @@ -45,6 +45,9 @@ def accept(self, task: Task): concept: Concept = Concept._conceptualize(self.concepts, task.term, conceptualize_budget) if concept is None: return None # The memroy is full. The concept fails to get into the memory. + # take out the concept, to update the budget + concept = self.concepts.take_by_key(key=task.term,remove=True) + # then process each task according to its type task_revised, goal_derived, answers_question, answer_quest = None, None, None, None if task.is_judgement: @@ -86,6 +89,9 @@ def accept(self, task: Task): # Build the concepts corresponding to the terms of those components within the task. concept.accept(task, self.concepts, conceptualize=False) + # put back the concept, to update the budget + self.concepts.put_back(item=concept,key=task.term) + if Enable.temporal_reasoning or Enable.operation: # if (!task.sentence.isEternal() && !(task.sentence.term instanceof Operation)) { # globalBuffer.eventInference(task, cont, false); //can be triggered by Buffer itself in the future From 40cc2cb6cc76ac93df3a4c2335a176cc5bb1f0d3 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Thu, 18 Jan 2024 15:49:58 -0500 Subject: [PATCH 6/7] Change item level properly when changing Concept budget --- pynars/NARS/DataStructures/_py/Concept.py | 34 ++++++++++++++--------- pynars/NARS/DataStructures/_py/Memory.py | 8 +++--- pynars/Narsese/_py/Sentence.py | 4 +-- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/pynars/NARS/DataStructures/_py/Concept.py b/pynars/NARS/DataStructures/_py/Concept.py index b1eac474..948f19bb 100644 --- a/pynars/NARS/DataStructures/_py/Concept.py +++ b/pynars/NARS/DataStructures/_py/Concept.py @@ -1,4 +1,6 @@ from typing import Tuple, Type, List, Union + +from pynars.NAL.Functions import Or from pynars.NAL.Functions.Tools import calculate_solution_quality, distribute_budget_among_links from pynars.NAL.Functions.BudgetFunctions import Budget_merge from pynars.Narsese import Belief, Task, Item, Budget, Sentence, Term, Task, Judgement, Goal @@ -139,22 +141,28 @@ def accept(self, task: Task, concepts: Bag=None, conceptualize: bool=True): self._build_task_links(concepts, task) self._build_term_links(concepts, task, budget) - def update_priority(self, p): + def update_priority(self, p, concepts: Bag): + concepts.take_by_key(key=self,remove=True) self.budget.priority = Or(self.budget.priority, p) + concepts.put(item=self) - def update_durability(self, d): + def update_durability(self, d, concepts: Bag): + concepts.take_by_key(key=self, remove=True) self.budget.durability = (Config.concept_update_durability_weight * d + (1-Config.concept_update_durability_weight)*self.budget.durability) + concepts.put(item=self) - def update_quality(self, q): + def update_quality(self, q, concepts: Bag): + concepts.take_by_key(key=self, remove=True) self.budget.quality = (Config.concept_update_quality_weight * q + (1-Config.concept_update_quality_weight)*self.budget.quality) + concepts.put(item=self) def _build_task_links(self, concepts: Bag, task: Task): '''''' budget = task.budget task_link = TaskLink(self, task, budget, True, index=[]) - self._insert_task_link(task_link) + self._insert_task_link(task_link, concepts) if self.term.is_atom: return sub_budget = budget.distribute(self.term.count()-1) # TODO: It seems that the budget is not the same with that in OpenNARS 3.0.4/3.1.0. Check here. for term in self.term.components: @@ -165,7 +173,7 @@ def _build_task_links(self, concepts: Bag, task: Task): indices = Link.get_index(self.term, term) for index in indices: task_link = TaskLink(concept, task, sub_budget, index=index) - concept._insert_task_link(task_link) + concept._insert_task_link(task_link, concepts) def _build_term_links(self, concepts: Bag, task: Task, budget: Budget): ''' @@ -192,24 +200,24 @@ def _build_term_links(self, concepts: Bag, task: Task, budget: Budget): indices = Link.get_index(self.term, term) for index in indices: - self._insert_term_link(TermLink(self, sub_concept, sub_budget, False, index=index)) - sub_concept._insert_term_link(TermLink(sub_concept, self, sub_budget, True, index=index)) + self._insert_term_link(TermLink(self, sub_concept, sub_budget, False, index=index), concepts) + sub_concept._insert_term_link(TermLink(sub_concept, self, sub_budget, True, index=index), concepts) sub_concept._build_term_links(concepts, task, sub_budget) - def _insert_task_link(self, task_link: TaskLink): + def _insert_task_link(self, task_link: TaskLink, concepts: Bag): self.task_links.put(task_link) # update the concept's budget using the link's budget - self.update_priority(task_link.budget.priority) - self.update_durability(task_link.budget.durability) + self.update_priority(task_link.budget.priority, concepts) + self.update_durability(task_link.budget.durability, concepts) # TODO: more handling. see OpenNARS 3.1.0 Concept.java line 318~366. - def _insert_term_link(self, term_link: TermLink): + def _insert_term_link(self, term_link: TermLink, concepts: Bag): self.term_links.put(term_link) # update the concept's budget using the link's budget - self.update_priority(term_link.budget.priority) - self.update_durability(term_link.budget.durability) + self.update_priority(term_link.budget.priority, concepts) + self.update_durability(term_link.budget.durability, concepts) # TODO: more handling. see OpenNARS 3.1.0 Concept.java line 318~366. @classmethod diff --git a/pynars/NARS/DataStructures/_py/Memory.py b/pynars/NARS/DataStructures/_py/Memory.py index 46b0e673..aeafd287 100644 --- a/pynars/NARS/DataStructures/_py/Memory.py +++ b/pynars/NARS/DataStructures/_py/Memory.py @@ -102,7 +102,7 @@ def accept(self, task: Task): def _accept_judgement(self, task: Task, concept: Concept): '''''' - belief_revised = None + belief_revised_task = None answers = { Question: [], Goal: [] } if Enable.operation: raise # InternalExperienceBuffer.handleOperationFeedback(task, nal); if Enable.anticipation: raise # ProcessAnticipation.confirmAnticipation(task, concept, nal); @@ -124,7 +124,7 @@ def _accept_judgement(self, task: Task, concept: Concept): } ''' raise - belief_revised = local__revision(task, belief) # TODO: handling the stamps + belief_revised_task: Task = local__revision(task, belief) # TODO: handling the stamps # reduce priority by achieving level task.reduce_budget_by_achieving_level(belief) @@ -147,9 +147,9 @@ def _accept_judgement(self, task: Task, concept: Concept): if goal_answer is not None: answers[Goal] = [goal_answer] # Modify the concept's Budget using the belief - if belief_revised is not None: concept.update_quality(belief_revised.sharpness) + if belief_revised_task is not None: concept.update_quality(belief_revised_task.sentence.sharpness, concepts=self.concepts) - return belief_revised, answers + return belief_revised_task, answers def _accept_question(self, task: Task, concept: Concept): '''''' diff --git a/pynars/Narsese/_py/Sentence.py b/pynars/Narsese/_py/Sentence.py index 79147545..979fc8cf 100644 --- a/pynars/Narsese/_py/Sentence.py +++ b/pynars/Narsese/_py/Sentence.py @@ -106,8 +106,8 @@ def directness(self): @property def sharpness(self): - if self.truth_value is None: return None - else: return 2 * abs(self.truth_value.e - 0.5) + if self.truth is None: return None + else: return 2 * abs(self.truth.e - 0.5) # @property # def temporal_order(self): From 86a75ed008fba16b7fea50e7b12feca09500b675 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Thu, 18 Jan 2024 15:56:38 -0500 Subject: [PATCH 7/7] Update Memory.py --- pynars/NARS/DataStructures/_py/Memory.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pynars/NARS/DataStructures/_py/Memory.py b/pynars/NARS/DataStructures/_py/Memory.py index aeafd287..1e348c99 100644 --- a/pynars/NARS/DataStructures/_py/Memory.py +++ b/pynars/NARS/DataStructures/_py/Memory.py @@ -45,9 +45,6 @@ def accept(self, task: Task): concept: Concept = Concept._conceptualize(self.concepts, task.term, conceptualize_budget) if concept is None: return None # The memroy is full. The concept fails to get into the memory. - # take out the concept, to update the budget - concept = self.concepts.take_by_key(key=task.term,remove=True) - # then process each task according to its type task_revised, goal_derived, answers_question, answer_quest = None, None, None, None if task.is_judgement: @@ -89,9 +86,6 @@ def accept(self, task: Task): # Build the concepts corresponding to the terms of those components within the task. concept.accept(task, self.concepts, conceptualize=False) - # put back the concept, to update the budget - self.concepts.put_back(item=concept,key=task.term) - if Enable.temporal_reasoning or Enable.operation: # if (!task.sentence.isEternal() && !(task.sentence.term instanceof Operation)) { # globalBuffer.eventInference(task, cont, false); //can be triggered by Buffer itself in the future