Skip to content

Commit

Permalink
feat: ✨ Optimize information class instruction
Browse files Browse the repository at this point in the history
Now the information of "current reasoner" "All registered operations" can be query through cmd
  • Loading branch information
ARCJ137442 committed Oct 30, 2023
1 parent fdc2c68 commit 5dbcd54
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 39 deletions.
88 changes: 57 additions & 31 deletions pynars/ConsolePlus.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def wait_answer(out_type: str, max_listens: int, *cmd_in_interval: str) -> List[

@cmd_register(('waitres', 'wait-result', 'w-result'), (int, 100), (str, '1'), (None, ''))
def wait_result(max_listens: int, cmd_in_interval: str, *target_sentences: List[str]) -> List[NARSOutput]:
'''Format: waitres [Maximum tolerance = 100] [Interval cmd = '1'] [sentences...]
'''Format: waitres [Maximum tolerance = 100] [Interval cmd = '1'] [*sentences]
Attempts to intercept output that matches the specified sentences (same NAL format) and stops when it appears'''
from pynars.Narsese import parser
# Parameter preprocessing ' '.join(str target statement)
Expand Down Expand Up @@ -248,15 +248,15 @@ def toggle_color() -> None:

@cmd_register('readfile', 'read-file')
def read_file(*args: List[str]) -> None:
'''Format: readfile [... file path]
'''Format: readfile [*file_paths]
Call API to read file'''
for path in args:
current_NARS_interface.execute_file(path)


@cmd_register(('history', 'history-input'))
def print_history_in(*args: List[str]) -> None:
'''Format: history [... placeholder]
'''Format: history [*placeholder]
Output the user's input history
Default: The Narsese seen at the bottom of the system, not the actual input
User actual input cmd: input any parameters can be obtained'''
Expand All @@ -266,7 +266,7 @@ def print_history_in(*args: List[str]) -> None:

@cmd_register('history-output')
def print_history_out(*args: List[str]) -> None:
'''Format: history-output [... placeholder]
'''Format: history-output [*placeholder]
Output the console's output history
Default: The Narsese seen at the bottom of the system, not the actual input
User actual input cmd: input any parameters can be obtained'''
Expand Down Expand Up @@ -299,8 +299,29 @@ def eval_code(*args: List[str]) -> None:
print(f'eval failed: {e}')


@cmd_register(('register-operation', 'register'))
def register_operation(*args: List[str]) -> None:
@cmd_register(('operation', 'operation-list', 'o-list'))
def operation_list(*keywords: List[str]) -> None:
'''Format: operation-list [*keywords]
Enumerate existing operations; It can be retrieved with parameters'''
keywords = keywords if keywords else ['']
# Search for a matching interface name
from pynars.NARS.Operation.Register import registered_operations, getRegisteredOperationByName, registeredOperationNames
operation_names: List[str] = prefix_browse(registeredOperationNames(), *keywords)
# Displays information about "matched interface"
if operation_names:
for name in operation_names: # match the list of all cmds, as long as they match the search results - not necessarily in order
op = getRegisteredOperationByName(name)
f = registered_operations[op]
print(f'''<Operation {str(op)}>: {
'No function' if f == None else
'No description' if f.__doc__.strip() == '' else
f.__doc__}''')
return
print(f'No Operation is browsed by "{", ".join(keywords)}"')


@cmd_register(('register-operation', 'operation-register', 'o-register', 'register'))
def operation_register(*args: List[str]) -> None:
'''Format: register-operation <Operation(Term) Name> [<'eval'/'exec'> <Python Code>]
Register an operation to NARS interface.
Expand All @@ -319,7 +340,7 @@ def execution_F(arguments: Iterable[Term], task: Task=None, memory: Memory=None)
print(f'executed: arguments={arguments}, task={task}, memory={memory}. the "task" will be returned')
return task
execution_F.__doc__ = f'''
The execution is auto generated from operator {name} without code
The execution is auto generated from operator with name={name} without code
'''.strip()
else:
eType = args[1]
Expand All @@ -331,15 +352,15 @@ def execution_F(arguments: Iterable[Term], task: Task=None, memory: Memory=None)
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}
The execution is auto generated from operator with name={name} in {eType} mode with code={code}
'''.strip()
if current_NARS_interface.reasoner.register_operation(name, execution_F):
print(f'Operation {name} was successfully registered ' + (
if (op:=current_NARS_interface.reasoner.register_operation(name, execution_F)) is not None:
print(f'Operation {str(op)} was successfully registered ' + (
'without code'
if len(args)
if len(args) == 1
else f'in mode "{eType}" with code={code}'))
else:
print(f'The operation {name} was already registered!')
print(f'The operation with name="{name}" was already registered!')


@cmd_register(('simplify-parse', 'parse'))
Expand All @@ -354,7 +375,7 @@ def toggle_simplify_parse() -> None:

@cmd_register('help')
def help(*keywords: List[str], search_in: Dict[tuple, tuple] = PRESET_CMDS) -> None:
'''Format: help [... specific cmd]
'''Format: help [*keywords]
Display this help document, or assist in retrieving help for additional cmds'''
# Core idea: Empty prefix = all cmds
keywords = keywords if keywords else ['']
Expand Down Expand Up @@ -445,7 +466,7 @@ def macro_show(name: str): return f'Macro {name}: \n' + \

@cmd_register(('macro-query', 'm-query'))
def macro_query(*args: List[str]) -> None:
'''Format: macro-query [... macro name]
'''Format: macro-query [*keywords]
With parameters: Find macros by name and display their internal commands (the number can be stacked indefinitely)
No arguments: Lists all defined macros and displays their internal commands'''
if args: # find by names
Expand All @@ -468,7 +489,7 @@ def macro_exec1(name: str) -> None:

@cmd_register(('macro-exec', 'm-exec'))
def macro_exec(*args: List[str]) -> None:
'''Format: macro-exec [... macro name]
'''Format: macro-exec [*keywords]
Execute macros by name (unlimited number can be stacked)
If empty, execute macro "" (empty string)'''
args = args if args else ['']
Expand Down Expand Up @@ -531,38 +552,43 @@ def current_nar_name() -> str:
return None


@cmd_register(('reasoner-current', 'r-current'))
@cmd_register(('reasoner-current', 'r-current', 'info'))
def reasoner_current() -> None:
'''Gets the name of the current reasoner'''
'''Gets the name and info of the current reasoner'''
name = current_nar_name()
if name != None:
print(f'The name of the current reasoner is "{name}".')
print('Current NARS interface:')
print(get_interface_info(name, interfaces[name]))


@cmd_register(('reasoner-list', 'r-list'))
@cmd_register(('reasoner-list', 'r-list', 'list'))
def reasoner_list(*keywords: List[str]) -> None:
'''Format: reasoner-list [... specific cmd]
'''Format: reasoner-list [*keywords]
Enumerate existing reasoners; It can be retrieved with parameters'''
keywords = keywords if keywords else ['']
# Search for a matching interface name
reasoner_names: List[str] = prefix_browse(interfaces, *keywords)
# Displays information about "matched interface"
if reasoner_names:
for name in reasoner_names: # match the list of all cmds, as long as they match the search results - not necessarily in order
interface: NARSInterface = interfaces[name]
information: str = '\n\t'+"\n\t".join(f"{name}: {repr(inf)}" for name, inf in [
('Memory', interface.reasoner.memory),
('Channels', interface.reasoner.channels),
('Overall Experience', interface.reasoner.overall_experience),
('Internal Experience', interface.reasoner.internal_experience),
('Sequence Buffer', interface.reasoner.sequence_buffer),
('Operations Buffer', interface.reasoner.operations_buffer),
])
print(f'<{name}>: {information}')
print(get_interface_info(name, interfaces[name]))
return
print(f'No reasoner is browsed by "{", ".join(keywords)}"')


def get_interface_info(name:str, interface: NARSInterface) -> str:
'''print the information of an NARS interface'''
information: str = '\n\t'+"\n\t".join(f"{name}: {repr(inf)}" for name, inf in [
('Memory', interface.reasoner.memory),
('Channels', interface.reasoner.channels),
('Overall Experience', interface.reasoner.overall_experience),
('Internal Experience', interface.reasoner.internal_experience),
('Sequence Buffer', interface.reasoner.sequence_buffer),
('Operations Buffer', interface.reasoner.operations_buffer),
])
return f'<{name}>: {information}'


@cmd_register(('reasoner-new', 'r-new'),
(str, 'unnamed'),
(int, 100),
Expand Down Expand Up @@ -839,7 +865,7 @@ def auto_execute_cmd_by_name(cmd_name: str, params: List[str], cmd_dict: Dict[tu
return False
else:
hint = 'Are you looking for "' + \
"\"|\"".join('/'.join(alias) for alias in name_alias_hints) + \
"\" | \"".join('/'.join(alias) for alias in name_alias_hints) + \
'"?' if name_alias_hints else ''
print(f'Unknown cmd {cmd_name}. {hint}')
return False
Expand Down
9 changes: 4 additions & 5 deletions pynars/NARS/Control/Reasoner.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,12 @@ def mental_operation(self, task: Task, concept: Concept, answers_question: Task,

return task_operation_return, task_executed, belief_awared

def register_operation(self, name_operation: str, callback: Callable) -> bool:
'''register an operation and return whether the registration is successful'''
'return the status of whether the registration is successful'
def register_operation(self, name_operation: str, callback: Callable):
'''register an operation and return the operation if successful (otherwise, return None)'''
if not Operation.isRegisteredByName(name_operation):
from pynars.Narsese import Operation as Op
op = Op(name_operation)
Operation.register(op, callback)
return True
return False
return op
return None

22 changes: 19 additions & 3 deletions pynars/NARS/Operation/Register.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,31 @@

registered_operations: Dict[Operation, Callable] = {}

def registeredOperationNames():
''''''
global registered_operations
return [registered_operation.word for registered_operation in registered_operations.keys()]


def register(operation: Operation, callable: Callable):
''''''
global registered_operations
registered_operations[operation] = callable

def isRegisteredByName(word) -> bool:

def isRegisteredByName(word):
''''''
global registered_operations
for registered_operation in registered_operations:
for registered_operation in registered_operations.keys():
if registered_operation.word == word:
return True
return False
return False


def getRegisteredOperationByName(word):
''''''
global registered_operations
for registered_operation in registered_operations.keys():
if registered_operation.word == word:
return registered_operation
return None

0 comments on commit 5dbcd54

Please sign in to comment.