diff --git a/Experiments/ExConsole/main.py b/Experiments/ExConsole/main.py index 606fe1e..cb8aa46 100644 --- a/Experiments/ExConsole/main.py +++ b/Experiments/ExConsole/main.py @@ -17,7 +17,7 @@ from random import randint # compatible type annotation -from typing import List, Dict, Tuple, Union +from typing import List, Dict, Tuple, Iterable # information @@ -207,24 +207,42 @@ def shared_memory_test() -> None: @exp_register('op') def operations_test() -> None: - task1: Task = NarseseParser.parse(' result>.') # auto parse - # term.type = TermType.STATEMENT # ! Only statements can be actions, not mandatory - statement1 = task1.term # term of the task + # register operation, the register of mental operations can be seen in pynars\NARS\InferenceEngine\GeneralEngine\Rules\NAL9.py + from pynars.NARS import Operation + def exeF(arguments: Iterable[Term], task: Task=None, memory: Memory=None) -> Union[Task,None]: + ''' + The execution should accepts arguments (terms), task(current) and current memory(to deal mental operations) + @return a task(is used to represent the new task generated) or None(no task is processed) + ''' + print(f'executed: arguments={arguments}, task={task}, memory={memory}. the "task" will be returned') + return task + Operation.register(Operation.Operation('f'), exeF) + # build task + # task1: Task = NarseseParser.parse('f(x).') # the same as <(*, x) --> ^f>. + # task1: Task = NarseseParser.parse('f(x).') # the same as <(*, x) --> ^f>. # * Force the term involved in the task to be set to "action", if is_executable = True - statement1.is_operation = True - print(f'Is operation? {statement1.is_executable}') + # print(f'Is operation? {task1.is_executable}') + # placing tasks directly into perceptual channels (Narsese channels can only pass text) + # current_NARS_interface.reasoner.perception_channel.put(task1) '''concept Concept: Concept = concept. _conceptualize( # Generate concept current_NARS_interface.reasoner.memory, term=statement Operation statement, Budget=budget(0.9, 0.9, 0.5) ) current_NARS_interface.reasoner.memory.concepts.put(concept) - # into the concept, but it does not seem to be associated with the task, the reasoner will not use it. - # ''' - # placing tasks directly into perceptual channels (Narsese channels can only pass text) - current_NARS_interface.reasoner.perception_channel.put(task1) - # Automatic reasoning five steps, let NAS put "antecedent" and "result" into the memory area + ''' + # into the concept, but it does not seem to be associated with the task, the reasoner will not use it. + # run other cmds + execute_input('5') + execute_input(' G>.') + execute_input('<(^f, x) ==> A>.') execute_input('5') + current_NARS_interface.input_narsese('G!') # avoid to be ! + # Automatic reasoning five steps, let NAS put "antecedent" and "result" into the memory area + execute_input('/waitans ACHIEVED') + # * it should be contained with two outputs: + # * `EXE :<(*, x)-->^f> = $0.022;0.225;0.644$ <(*, x)-->^f>! %1.000;0.287% {None: 2, 1, 0}` + # * `ACHIEVED:<(*, x)-->^f>. :\: %1.000;0.900%` # print concept list print(show_bag(current_NARS_interface.reasoner.memory.concepts)) diff --git a/pynars/Config.py b/pynars/Config.py index f595bbe..d0c12b6 100644 --- a/pynars/Config.py +++ b/pynars/Config.py @@ -10,7 +10,7 @@ raise "please install the module by `pip install jstyleson`" class Enable: - temporal_rasoning = False + temporal_reasoning = False variable = True anticipation = False operation = False diff --git a/pynars/ConsolePlus.py b/pynars/ConsolePlus.py index f12fa6d..13d1cdc 100644 --- a/pynars/ConsolePlus.py +++ b/pynars/ConsolePlus.py @@ -1,14 +1,11 @@ -from typing import List, Dict, Tuple, Union -from typing import List +from typing import List, Dict, Tuple, Union, Iterable import functools import re from pynars.Interface import narsese_parse_safe +from pynars.Narsese import Term,Task +from pynars.NARS.DataStructures import Memory -from pynars.Interface import NARSInterface -from pynars.Interface import NARSOutput -from pynars.Interface import PrintType -from pynars.Interface import Reasoner -from pynars.Interface import print_out_origin +from pynars.Interface import NARSInterface,NARSOutput,PrintType,Reasoner,print_out_origin print_output = print_out_origin # compatible type annotation @@ -258,14 +255,55 @@ def print_history(*args: List[str]) -> None: def exec_code(*args: List[str]) -> None: '''Format: exec Directly invoke Python's built-in exec cmd to execute a single line of code''' - exec(' '.join(args)) + code = " ".join(args) + print(f'[exec]{code}') + try: + exec(code) + except BaseException as e: + print(f'exec failed: {e}') @cmd_register(('evaluate', 'eval')) def eval_code(*args: List[str]) -> None: '''Format: eval Directly invoke Python's built-in eval cmd to evaluate a single line of code''' - print(f'eval result: {eval(" ".join(args))}') + code = " ".join(args) + print(f'[eval]{code}') + try: + print(f'eval result: {eval(code)}') + except BaseException as e: + print(f'eval failed: {e}') + + +@cmd_register(('register-operation', 'register')) +def register_operation(*args: List[str]) -> None: + '''Format: register-operation <"eval"/"exec"> + Register an operation to the whole PyNARS instance. + function signature: + execution_F(arguments: Iterable[Term], task: Task=None, memory: Memory=None) -> Union[Task,None] + ! Unsupported: register mental operations + ''' + name = args[0] + eType = args[1] + code = " ".join(args[2:]) + if code == '': + def execution_F(arguments: Iterable[Term], task: Task=None, memory: Memory=None) -> Union[Task,None]: + print(f'executed: arguments={arguments}, task={task}, memory={memory}. the "task" will be returned') + return task + else: + if eType =='exec': + def execution_F(arguments: Iterable[Term], task: Task=None, memory: Memory=None) -> Union[Task,None]: + return exec(code) + else: + def execution_F(arguments: Iterable[Term], task: Task=None, memory: Memory=None) -> Union[Task,None]: + return eval(code) + execution_F.__doc__ = f''' + The execution is auto generated from operator {name} in {eType} mode with code={code} + ''' + from pynars.NARS.Operation.Register import register + from pynars.NARS.Operation import Operation + register(Operation(name), execution_F) + print(f'Operation {name} was successfully registered in mode "{eType}" with code={code}') @cmd_register(('simplify-parse', 'parse')) diff --git a/pynars/NAL/Inference/LocalRules.py b/pynars/NAL/Inference/LocalRules.py index 06761cc..65f670f 100644 --- a/pynars/NAL/Inference/LocalRules.py +++ b/pynars/NAL/Inference/LocalRules.py @@ -26,7 +26,7 @@ def revision(task: Task, belief: Task, budget_tasklink: Budget=None, budget_term premise2: Union[Judgement, Goal] = belief.sentence truth1 = premise1.truth truth2 = premise2.truth - if Enable.temporal_rasoning: + if Enable.temporal_reasoning: # boolean useNewBeliefTerm = intervalProjection(nal, newBelief.getTerm(), oldBelief.getTerm(), beliefConcept.recent_intervals, newTruth); raise truth = Truth_revision(truth1, truth2) diff --git a/pynars/NAL/MentalOperation/_execute.py b/pynars/NAL/MentalOperation/_execute.py index 49c22ab..6aecaf7 100644 --- a/pynars/NAL/MentalOperation/_execute.py +++ b/pynars/NAL/MentalOperation/_execute.py @@ -1,4 +1,4 @@ -from typing import List +from typing import Callable, List from pynars.Config import Config from pynars.Narsese._py.Budget import Budget from pynars.Narsese._py.Operation import * @@ -23,7 +23,7 @@ def execute(task: Task): return None def anticipate(task: Task, *args: Term): - '''''' + '''TODO''' def believe(statement: Term, term_truth: Term): '''''' @@ -37,7 +37,7 @@ def believe(statement: Term, term_truth: Term): def doubt(beliefs: List[Belief]): '''''' for belief in beliefs: - # discount the confidence of the beleif + # discount the confidence of the belief belief.truth.c = belief.truth.c * Config.rate_discount_c return None @@ -74,3 +74,12 @@ def wonder(statement: Term): sentence = Question(statement, stamp=stamp) return Task(sentence, budget) + +def register(term: Term, callable: Callable=lambda arguments, task, memory: print(f'operation "{task.term.word}" is executed with arguments {arguments}')): + '''let a term be used as an operator''' + try: + from pynars.NARS.Operation.Register import register + register(term, callable) + except BaseException as e: + print(e) + return None diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index 075d4e6..4298fbb 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -85,13 +85,14 @@ def cycle(self): # if task.is_goal: # goal_revised = self.process_goal(task, concept) judgement_revised, goal_revised, answers_question, answers_quest, (task_operation_return, task_executed), _tasks_derived = self.memory.accept(task) - if task_operation_return is not None: tasks_derived.append(task_operation_return) + if task_operation_return is not None: + tasks_derived.append(task_operation_return) # if task_executed is not None: tasks_derived.append(task_executed) tasks_derived.extend(_tasks_derived) # self.sequence_buffer.put_back(task) # globalBuffer.putBack(task, # narParameters.GLOBAL_BUFFER_FORGET_DURATIONS, this) - if Enable.temporal_rasoning: + if Enable.temporal_reasoning: # TODO: Temporal Inference # Ref: OpenNARS 3.1.0 line 409~411 # if (!task.sentence.isEternal() && !(task.sentence.term instanceof Operation)) { @@ -124,7 +125,7 @@ def cycle(self): self.memory.put_back(concept) # temporal induction in NAL-7 - if False and task is not None and task.is_judgement and task.is_external_event: + if Enable.temporal_reasoning and 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) t1 = time() tasks_derived.extend( @@ -140,7 +141,7 @@ def cycle(self): pass # TODO: select a task from `self.sequence_buffer`? # mental operation of NAL-9 - if False: + if Enable.operation: # it should be `Enable.mental_operation`? task_operation_return, task_executed, belief_awared = self.mental_operation(task, concept, answers_question, answers_quest) if task_operation_return is not None: tasks_derived.append(task_operation_return) @@ -153,8 +154,8 @@ def cycle(self): # handle the sense of time Global.time += 1 - thresh_compexity = 20 - tasks_derived = [task for task in tasks_derived if task.term.complexity <= thresh_compexity] + thresh_complexity = 20 + tasks_derived = [task for task in tasks_derived if task.term.complexity <= thresh_complexity] return tasks_derived, judgement_revised, goal_revised, answers_question, answers_quest, ( task_operation_return, task_executed) diff --git a/pynars/NARS/DataStructures/_py/Concept.py b/pynars/NARS/DataStructures/_py/Concept.py index 5fa3f81..05dc105 100644 --- a/pynars/NARS/DataStructures/_py/Concept.py +++ b/pynars/NARS/DataStructures/_py/Concept.py @@ -65,7 +65,7 @@ def term(self) -> Term: def get_belief(self) -> Belief: '''''' - if Enable.temporal_rasoning: + if Enable.temporal_reasoning: # final Sentence belief = beliefT.sentence; # nal.emit(BeliefSelect.class, belief); # nal.setTheNewStamp(taskStamp, belief.stamp, currentTime); @@ -202,7 +202,7 @@ def _conceptualize(cls, concepts: Bag, term: Term, budget: Budget): If the concept of the task is already in the memory, then merge the concept into the existed one. Otherwise, make up a new concept and add it into the memory. ''' - if Enable.temporal_rasoning: + if Enable.temporal_reasoning: # if(term instanceof Interval) { # return null; # } diff --git a/pynars/NARS/DataStructures/_py/Memory.py b/pynars/NARS/DataStructures/_py/Memory.py index 6e968a8..2cfa07e 100644 --- a/pynars/NARS/DataStructures/_py/Memory.py +++ b/pynars/NARS/DataStructures/_py/Memory.py @@ -74,7 +74,7 @@ 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_rasoning or Enable.operation: + 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 # } @@ -94,7 +94,7 @@ def _accept_judgement(self, task: Task, concept: Concept): if belief is not None: # j2: Judgement = belief.sentence if revisible(task, belief): - if Enable.temporal_rasoning: + if Enable.temporal_reasoning: ''' nal.setTheNewStamp(newStamp, oldStamp, nal.time.time()); final Sentence projectedBelief = oldBelief.projection(nal.time.time(), newStamp.getOccurrenceTime(), concept.memory); @@ -245,8 +245,8 @@ def _accept_goal(self, task: Task, concept: Concept, task_link: TaskLink=None): op = stat.predicate from pynars.NARS.Operation.Register import registered_operations from pynars.NARS.Operation.Execution import execute + # ! if `op` isn't registered, an error "AttributeError: 'NoneType' object has no attribute 'stamp'" from "key: Callable[[Task], Any] = lambda task: (hash(task), hash(task.stamp.evidential_base))" will be raised if op in registered_operations and not task.is_mental_operation: - # to judge whether the goal has been fulfilled task_operation_return, task_executed = execute(task, concept, self) concept_task = self.take_by_key(task.term, remove=False) diff --git a/pynars/NARS/Operation/Interface_Execution.py b/pynars/NARS/Operation/Interface_Execution.py index 0b54ec2..c3dad4f 100644 --- a/pynars/NARS/Operation/Interface_Execution.py +++ b/pynars/NARS/Operation/Interface_Execution.py @@ -44,3 +44,7 @@ def execute__want(arguments: Iterable[Term], task: Task=None, memory: Memory=Non return _execute.want(statement) +def execute__register(arguments: Iterable[Term], task: Task=None, memory: Memory=None): + '''let a term be used as an operator''' + term = arguments[1] + return _execute.register(term) diff --git a/pynars/Narsese/_py/Operation.py b/pynars/Narsese/_py/Operation.py index 9444df4..6ce4d54 100644 --- a/pynars/Narsese/_py/Operation.py +++ b/pynars/Narsese/_py/Operation.py @@ -22,11 +22,69 @@ def do_hashing(self): self._hash_value = hash(str(self)) return self._hash_value - Anticipate = Operation('anticipate', True, is_mental_operation=True) -Believe = Operation('believe', True, is_mental_operation=True) -Doubt = Operation('doubt', True, is_mental_operation=True) Evaluate = Operation('evaluate', True, is_mental_operation=True) -Hesitate = Operation('hesitate', True, is_mental_operation=True) -Want = Operation('want', True, is_mental_operation=True) -Wonder = Operation('wonder', True, is_mental_operation=True) \ No newline at end of file + +# With reference to book NAL(2012) +Observe = Operation('observe', True, is_mental_operation=True) +'''get an active task from the task buffer''' + +Expect = Operation('expect', True, is_mental_operation=True) +'''check the input for a given statement''' + +Know = Operation('know', True, is_mental_operation=True) +'''find the truth-value of a statement''' + +Assess = Operation('assess', True, is_mental_operation=True) +'''find the desire-value of a statement''' + +Believe = Operation('believe', True, is_mental_operation=True) +'''turn a statement into a task containing a judgment''' + +Want = Operation('want', True, is_mental_operation=True) +'''turn a statement into a task containing a goal''' + +Wonder = Operation('wonder', True, is_mental_operation=True) +'''turn a statement into a task containing a question''' + +Remember = Operation('remember', True, is_mental_operation=True) +'''turn a statement into a belief''' + +Consider = Operation('consider', True, is_mental_operation=True) +'''do inference on a concept''' + +Remind = Operation('remind', True, is_mental_operation=True) +'''activate a concept''' + +Doubt = Operation('doubt', True, is_mental_operation=True) +'''decrease the confidence of a belief''' + +Hesitate = Operation('hesitate', True, is_mental_operation=True) +'''decrease the confidence of a goal''' + +Assume = Operation('assume', True, is_mental_operation=True) +'''temporarily take a statement as a belief''' + +Name = Operation('name', True, is_mental_operation=True) +'''create a simple internal ID to a useful compound term''' + +Wait = Operation('wait', True, is_mental_operation=True) +'''pause the system’s action for a given number of working cycles''' + +Repeat = Operation('repeat', True, is_mental_operation=True) +'''execute an action repeatedly under a given condition''' + +Tell = Operation('tell', True, is_mental_operation=True) +'''produce an outgoing task containing a judgment''' + +Demand = Operation('demand', True, is_mental_operation=True) +'''produce an outgoing task containing a goal''' + +Ask = Operation('ask', True, is_mental_operation=True) +'''produce an outgoing task containing a question''' + +Check = Operation('check', True, is_mental_operation=True) +'''produce an outgoing task containing a query''' + +Register = Operation('register', True, is_mental_operation=True) +'''let a term be used as an operator'''