diff --git a/Experiments/ExConsole/data2nal.py b/Experiments/ExConsole/data2narsese.py similarity index 62% rename from Experiments/ExConsole/data2nal.py rename to Experiments/ExConsole/data2narsese.py index 7073a61..587f9bc 100644 --- a/Experiments/ExConsole/data2nal.py +++ b/Experiments/ExConsole/data2narsese.py @@ -1,7 +1,11 @@ -'''Data to NAL +'''Data to Narsese Define a format for converting Python data structures to Narsese -Core function: -''' +Core function: + +'''# compatible type annotation +from typing import List, Dict, Tuple, Union + + from pynars.Narsese import Punctuation from pynars.Narsese import parser # pynars @@ -31,7 +35,7 @@ def is_basic_type(obj: any) -> bool: return obj == None or t == bool or t == int or t == float or t == str -def verify_term_name(name: str) -> str | None: +def verify_term_name(name: str) -> Union[str,None]: try: return ( name @@ -44,7 +48,10 @@ def verify_term_name(name: str) -> str | None: def term_rel(A: str, B: str) -> str: - '''Construct the term "Relationship between A and B"''' + ''' + Construct the term "Relationship between A and B + Narsese representation: (*, A, B) + "''' return f'(*,{A},{B})' @@ -66,25 +73,32 @@ def term_name(A: any) -> str: # sentence construction -def sentence_inh(A: str, B: str, punct: Punctuation | str = Punctuation.Judgement) -> str: - '''Building relationships "A is B"''' +def sentence_inheritance(A: str, B: str, punct: Union[Punctuation,str] = Punctuation.Judgement) -> str: + ''' + Building relationships "A is B" + Narsese representation: B> + ''' return f'<{A} --> {B}>{punct.value if isinstance(punct,Punctuation) else punct}' # B> default with "." def sentence_rel(A: str, r: str, B: str, punct: Punctuation = Punctuation.Judgement) -> str: - '''Construct relation "ArB" i.e. "The relation between A and B" is r"''' - return sentence_inh(term_rel(A, B), f'{r}', punct=punct) # <(*,A,B) --> r>. The "relationship" between A and B is r + ''' + Construct relation "ArB" i.e. "The relation between A and B" is r" + Narsese representation: <(*, A, B) --> r> + ''' + return sentence_inheritance(term_rel(A, B), f'{r}', punct=punct) # <(*,A,B) --> r>. The "relationship" between A and B is r def sentence_type_sign(name: str, type: type, punct: Punctuation = Punctuation.Judgement) -> str: '''Name the name based on the type of the object''' - return sentence_inh(name, SIGN_TYPE_NAMES(type), punct=punct) # name --> type + return sentence_inheritance(name, SIGN_TYPE_NAMES(type), punct=punct) # name --> type def sentence_tri_rel(obj: str, key: str, value: str, relation: str = SIGN_RELATION_OBJ_PROPERTY_VALUE, punct: Punctuation = Punctuation.Judgement) -> str: - '''Building a ternary relationship "Object [key] = value" - Example: (*,{object},(*,{attribute},{value})) --> object_attribute_value + ''' + Building a ternary relationship "Object [key] = value" + Example: <(*,{object},(*,{attribute},{value})) --> object_attribute_value> ''' return sentence_rel(obj, relation, term_rel(key, value), punct=punct) # (*,{obj},(*,{key},{value})) --> relation @@ -94,36 +108,36 @@ def sentence_tri_rel(obj: str, key: str, value: str, relation: str = SIGN_RELATI # Use kwargs to automatically pass "punctuation" information -def none2NAL(n: None, special_name: str, **kwargs) -> list[str]: - '''None to NAL''' +def none2Narsese(n: None, special_name: str, **kwargs) -> List[str]: + '''None to Narsese''' return [sentence_type_sign(special_name, type(n), **kwargs)] -def bool2NAL(b: str, special_name: str, **kwargs) -> list[str]: - '''boolean to NAL''' - result: list[str] = [sentence_type_sign( +def bool2Narsese(b: str, special_name: str, **kwargs) -> List[str]: + '''boolean to Narsese''' + result: List[str] = [sentence_type_sign( special_name, bool, **kwargs)] # preset type identification return result -def int2NAL(i: int, special_name: str, **kwargs) -> list[str]: - '''Integer to NAL +def int2Narsese(i: int, special_name: str, **kwargs) -> List[str]: + '''Integer to Narsese TODO: Build an integer system''' - result: list[str] = [sentence_type_sign( + result: List[str] = [sentence_type_sign( special_name, int, **kwargs)] # preset type identification return result -def float2NAL(f: float, special_name: str, **kwargs) -> list[str]: - '''Floating-point number becomes NAL +def float2Narsese(f: float, special_name: str, **kwargs) -> List[str]: + '''Floating-point number becomes Narsese TODO: Build a floating point number system and combine it with an integer system''' - result: list[str] = [sentence_type_sign( + result: List[str] = [sentence_type_sign( special_name, float, **kwargs)] # preset type identification return result -def str2NAL(s: str, special_name: str, **kwargs) -> list[str]: - '''Set to NAL +def str2Narsese(s: str, special_name: str, **kwargs) -> List[str]: + '''Set to Narsese TODO: How does distinguish between "name" and "value" of a string?''' # tests whether a string can be directly accepted as a term, appended if it is, unappended if it is not # Try to use the string itself as a name for easy identification @@ -131,28 +145,28 @@ def str2NAL(s: str, special_name: str, **kwargs) -> list[str]: final_name: str = special_name + \ (f'「{s}」' if final_name else '') # Include itself if you can, do not add information otherwise # preset type identification - result: list[str] = [sentence_type_sign(final_name, str, **kwargs)] + result: List[str] = [sentence_type_sign(final_name, str, **kwargs)] return result # containers -def set2NAL(s: set, special_name: str, **kwargs) -> list[str]: - '''Set to NAL +def set2Narsese(s: set, special_name: str, **kwargs) -> List[str]: + '''Set to Narsese Use the relative item "belong" - Import a collection name as the concept name, and then convert all elements within it to NAL - Return: A list of multiple NAL statements (easy to split)''' - result: list[str] = [sentence_type_sign( + Import a collection name as the concept name, and then convert all elements within it to Narsese + Return: A list of multiple Narsese statements (easy to split)''' + result: List[str] = [sentence_type_sign( special_name, set, **kwargs)] # preset type identification - for item in s: # TODO: Implementing recursive logic @auto2NAL(item) + for item in s: # TODO: Implementing recursive logic @auto2Narsese(item) result.append(sentence_rel(term_name(item), SIGN_RELATION_BELONG, special_name, **kwargs)) return result -def lis_tuple2NAL(array: list | tuple, special_name: str, **kwargs) -> List[str]: - '''List/tuple to NAL: Lists whose keys are integers''' - result: list[str] = [sentence_type_sign( +def lis_tuple2Narsese(array: Union[list,tuple], special_name: str, **kwargs) -> List[str]: + '''List/tuple to Narsese: Lists whose keys are integers''' + result: List[str] = [sentence_type_sign( special_name, type(array), **kwargs)] # preset type identification for i in range(len(array)): # get element @@ -160,29 +174,29 @@ def lis_tuple2NAL(array: list | tuple, special_name: str, **kwargs) -> List[str] iName: str = term_name(i) item_name: str = term_name(item) # pre-add definitions for keys and values - result.extend(auto2NAL(item, item_name, **kwargs)) - result.extend(auto2NAL(i, iName, **kwargs)) + result.extend(auto2Narsese(item, item_name, **kwargs)) + result.extend(auto2Narsese(i, iName, **kwargs)) # bind objects, keys, and values result.append(sentence_tri_rel( special_name, iName, item_name, - **kwargs)) # list[integer_index] = value + **kwargs)) # List[integer_index] = value return result -def dict2NAL(d: dict, special_name: str, **kwargs) -> list[str]: - '''dict to NAL - #! In fact, JSON is a dictionary, to achieve the dictionary↔NAL conversion, which is equivalent to NARS can read JSON +def dict2Narsese(d: dict, special_name: str, **kwargs) -> List[str]: + '''dict to Narsese + #! In fact, JSON is a dictionary, to achieve the dictionary↔Narsese conversion, which is equivalent to NARS can read JSON TODO models dictionaries using an index system''' - result: list[str] = [sentence_type_sign( + result: List[str] = [sentence_type_sign( special_name, dict, **kwargs)] # preset type identification for key, value in d.items(): key_name: str = term_name(key) value_name: str = term_name(value) # pre-add definitions for keys and values - result.extend(auto2NAL(key, key_name, **kwargs)) - result.extend(auto2NAL(value, value_name, **kwargs)) + result.extend(auto2Narsese(key, key_name, **kwargs)) + result.extend(auto2Narsese(value, value_name, **kwargs)) # bind objects, keys, and values result.append(sentence_tri_rel( special_name, @@ -192,16 +206,16 @@ def dict2NAL(d: dict, special_name: str, **kwargs) -> list[str]: return result -def type2NAL(t: type, special_name: str, **kwargs) -> list[str]: - '''Type to NAL - The "type" itself also needs to become NAL''' +def type2Narsese(t: type, special_name: str, **kwargs) -> List[str]: + '''Type to Narsese + The "type" itself also needs to become Narsese''' return [sentence_type_sign(special_name, type, **kwargs)] # only type notations # default values -def default2NAL(obj: any, special_name: str, **kwargs) -> list[str]: - '''Other objects become NAL +def default2Narsese(obj: any, special_name: str, **kwargs) -> List[str]: + '''Other objects become Narsese Temporarily occupy the one place, will later be separated from many types''' print(f'WARNING: unsupported object {obj} with type {type(obj)}') # only type notations @@ -210,23 +224,23 @@ def default2NAL(obj: any, special_name: str, **kwargs) -> list[str]: # Main function: Integrate all parts # -CONVERT_FUNCTIONS: dict[type:any] = { - type(None): none2NAL, - int: int2NAL, - float: float2NAL, - bool: bool2NAL, - str: str2NAL, - list: lis_tuple2NAL, - tuple: lis_tuple2NAL, - set: set2NAL, - dict: dict2NAL, - type: type2NAL, - None: default2NAL, +CONVERT_FUNCTIONS: Dict[type:any] = { + type(None): none2Narsese, + int: int2Narsese, + float: float2Narsese, + bool: bool2Narsese, + str: str2Narsese, + list: lis_tuple2Narsese, + tuple: lis_tuple2Narsese, + set: set2Narsese, + dict: dict2Narsese, + type: type2Narsese, + None: default2Narsese, } -def auto2NAL(obj: any, name: str = None, punct: Punctuation = Punctuation.Judgement) -> list[str]: - '''Function integration: Python object →NAL statement sequence +def auto2Narsese(obj: any, name: str = None, punct: Punctuation = Punctuation.Judgement) -> List[str]: + '''Function integration: Python object →Narsese statement sequence Automatically identify the object type and call the corresponding conversion function''' # get name # If no, automatically generate @@ -234,7 +248,7 @@ def auto2NAL(obj: any, name: str = None, punct: Punctuation = Punctuation.Judgem # get type t = type(obj) # select & Generate, with default values (all parameters must accept a "Narsese parsed name") - nars_sentences: list[str] = CONVERT_FUNCTIONS.get( + nars_sentences: List[str] = CONVERT_FUNCTIONS.get( t, CONVERT_FUNCTIONS[None])(obj, name, punct=punct) # verify for sentence in nars_sentences: diff --git a/Experiments/ExConsole/main.py b/Experiments/ExConsole/main.py index e43a900..96addac 100644 --- a/Experiments/ExConsole/main.py +++ b/Experiments/ExConsole/main.py @@ -16,12 +16,14 @@ # other native modules from random import randint +# compatible type annotation +from typing import List, Dict, Tuple, Union # information def show_bag(bag: Bag, sep: str = ',', indent_count: int = 1) -> str: '''Relation of extension: Channel -> Buffer -> Bag''' - not_none_levels: list[list] = [ + not_none_levels: List[list] = [ level_list for level_list in bag.levels if level_list] if not_none_levels: sep = sep + '\n' + "\t"*indent_count @@ -68,10 +70,10 @@ def show_information(): ## Main program ## -EXPERIMENTAL_CMDS: dict[tuple[str]:tuple[any, tuple[str]]] = {} +EXPERIMENTAL_CMDS: Dict[Tuple[str],Tuple[any, Tuple[str]]] = {} -def exp_register(*cmd_names: tuple[str]): +def exp_register(*cmd_names: Tuple[str]): '''Mimic from `cmd_register` in "Interface.py" It's no need of parameters because the experimental functions can utilize all of global variable''' def decorator(func): @@ -240,7 +242,7 @@ def chain_inference_test() -> None: @exp_register('json') def JSON_test() -> None: '''Input a series of numbers and construct a set, allowing NARS to determine ownership''' - from data2nal import auto2NAL, SIGN_RELATION_BELONG + from Experiments.ExConsole.data2narsese import auto2NAL, SIGN_RELATION_BELONG n: int = int(input('Please enter the number: ')) f: set = {x for x in range(n)} sN: str = f'Num0to{n}' @@ -256,7 +258,7 @@ def JSON_test() -> None: @exp_register('json') def JSON_test2() -> None: '''Enter a custom dictionary and ask for relationships one by one''' - from data2nal import auto2NAL + from Experiments.ExConsole.data2narsese import auto2NAL print('JSON Test Part II:') dic: dict = { 'smallest_positive_integer': 1, @@ -280,7 +282,7 @@ def JSON_test3() -> None: '''Enter a Config.json object that acts as its own "system parameter"''' print('JSON Test Part III') from pynars.Interface import DEFAULT_CONFIG - from data2nal import auto2NAL + from Experiments.ExConsole.data2narsese import auto2NAL show_information() execute_input(*auto2NAL(DEFAULT_CONFIG, 'system_config', punct=Punctuation.Judgement)) @@ -294,7 +296,7 @@ def JSON_test3() -> None: @exp_register('eval') def py_object_load_in() -> None: '''Load any Python object into NARS''' - from data2nal import auto2NAL + from Experiments.ExConsole.data2narsese import auto2NAL obj: any = None while not obj: try: @@ -306,7 +308,7 @@ def py_object_load_in() -> None: 'Please enter a name for this object (leave blank for automatic generation): ') punct: str = input( 'Please enter your modality for the object (./?/!) (Leave blank default.): ') - nals: list[str] = auto2NAL( + nals: List[str] = auto2NAL( obj, punct=punct if punct else '.', name=name if name else None) print(f'Input object: {repr(obj)}\nNAL text: \n' + "\n".join(nals)) execute_input(*nals) diff --git a/pynars/ConsolePlus.py b/pynars/ConsolePlus.py index cf7a63b..f12fa6d 100644 --- a/pynars/ConsolePlus.py +++ b/pynars/ConsolePlus.py @@ -1,3 +1,4 @@ +from typing import List, Dict, Tuple, Union from typing import List import functools import re @@ -10,6 +11,8 @@ from pynars.Interface import print_out_origin print_output = print_out_origin +# compatible type annotation + ## Cmd system ## @@ -34,7 +37,7 @@ def wrapper(*args, **kwargs): return decorator -def prefix_browse(to_browse: list[str], *keywords: list[str]) -> list[str]: +def prefix_browse(to_browse: List[str], *keywords: List[str]) -> List[str]: '''Matches the content against the string prefix''' return [string # returns cmd names # find matching cmds by: do not repeat @@ -45,7 +48,7 @@ def prefix_browse(to_browse: list[str], *keywords: list[str]) -> list[str]: for prefix in keywords)] -def prefix_cmd_browse(cmd_dict: dict[tuple:tuple], *keywords: list[str]) -> list[tuple[str]]: +def prefix_cmd_browse(cmd_dict: Dict[tuple, tuple], *keywords: List[str]) -> List[Tuple[str]]: '''Matches the content against the string prefix''' return [alias_indices # returns cmd names # find matching cmds by: do not repeat @@ -57,10 +60,10 @@ def prefix_cmd_browse(cmd_dict: dict[tuple:tuple], *keywords: list[str]) -> list for keyword in keywords)] # match the list of all cmds, as long as they match the search results - not necessarily in order -def quick_convert_cmd_types(inp: list[str], type_N_default: list[tuple[type, any]]) -> list[str]: +def quick_convert_cmd_types(inp: List[str], type_N_default: List[Tuple[type, any]]) -> List[str]: '''Constructs the parameter set of the final input cmd handler by specifying the type-default parameter list, combined with the input parameter list (using positional parameters)''' if type_N_default: - result: list[any] = [] + result: List[any] = [] lp = len(inp) for index in range(len(type_N_default)): # if has default values param_type, default_value = type_N_default[index] @@ -92,25 +95,25 @@ def quick_convert_cmd_types(inp: list[str], type_N_default: list[tuple[type, any The main functions of each function, and their respective types and roles of parameters and outputs: 1. wait_ans try to get the result: try to capture the output of the specified type, and stop when it appears -- Parameter: paras (list[str]), which contains the output type, maximum tolerance, and interval cmd -- Output: list[NARSOutput], captured output of the specified type +- Parameter: paras (List[str]), which contains the output type, maximum tolerance, and interval cmd +- Output: List[NARSOutput], captured output of the specified type 2. toggle_silent switches silent mode: Switches the silent mode of the cmd, generally blocking NARSOutput information -- Parameter: args (list[str]). No parameter is required +- Parameter: args (List[str]). No parameter is required - The output is None 3. readfile Read files: Call API to read files -- Parameter: args (list[str]), which contains the file path +- Parameter: args (List[str]), which contains the file path - The output is None 4. print_history Output history: Output user input history -- Parameter: args (list[str]), placeholder +- Parameter: args (List[str]), placeholder - The output is None 5. exec execution command: Directly invoke Python's built-in exec command to execute a single line of code -- Parameter: args (list[str]), which contains the code to be executed +- Parameter: args (List[str]), which contains the code to be executed - The output is None 6. parse switch shorthand escape: Switch command "automatic shorthand parsing" function -- Parameter: args (list[str]). No parameter is required +- Parameter: args (List[str]). No parameter is required - The output is None 7. help: Display the help document -- Parameter: args (list[str]), which contains specific commands +- Parameter: args (List[str]), which contains specific commands - The output is None # Externally defined variable types, meanings and relationships: @@ -125,10 +128,10 @@ def quick_convert_cmd_types(inp: list[str], type_N_default: list[tuple[type, any 6. parse toggle shorthand escape depends on parse_needSlash escape requires slash and out_print output directly 7. The help help depends on the PRE_CMD_PRESET cmd index and the helpDoc single cmd ''' -PRESET_CMDS: dict[tuple:tuple] = {} +PRESET_CMDS: Dict[tuple, tuple] = {} -def cmd_register(cmd_name: str | tuple[str], *type_N_default: list[tuple[type, any]]): +def cmd_register(cmd_name: Union[str, Tuple[str]], *type_N_default: List[Tuple[type, any]]): '''Decorator: Used to encapsulate cmds Automatically register cmds at function definition time through the specified Type - Default parameter list ! Encapsulated function becomes a "callable object" @@ -166,13 +169,13 @@ def decorated(*args, **kwargs): @cmd_register(('waitans', 'wait-answer', 'w-answer'), (str, 'ANSWER'), (int, 100), (None, '1')) -def wait_answer(out_type: str, max_listens: int, *cmd_in_interval: str) -> list[NARSOutput]: +def wait_answer(out_type: str, max_listens: int, *cmd_in_interval: str) -> List[NARSOutput]: '''Format: waitans [Output type = ANSWER] [Maximum tolerance = 100] [Interval cmd = '1'] Attempts to capture output of a specified type and stops when it appears''' # Parameter preprocessing: Concatenates cmds separated by Spaces cmd_in_interval: str = ' '.join(cmd_in_interval) out_type = PrintType.__getattribute__(PrintType, out_type) - outs: list[NARSOutput] + outs: List[NARSOutput] while max_listens < 0 or (max_listens := max_listens-1): # Loop execute interval cmd (default is wait statement) outs = current_NARS_interface.input_narsese(cmd_in_interval) @@ -184,7 +187,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]: +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...] Attempts to intercept output that matches the specified sentences (same NAL format) and stops when it appears''' from pynars.Narsese import parser @@ -195,7 +198,7 @@ def wait_result(max_listens: int, cmd_in_interval: str, *target_sentences: list[ # Using special syntax +NAL parser, reconvert to NAL standard format target_sentences: str = parser.parse(target_sentences).sentence.repr() # starting wait - outs: list[NARSOutput] + outs: List[NARSOutput] while max_listens < 0 or (max_listens := max_listens-1): # Loop execute interval cmd (default is wait statement) outs = current_NARS_interface.input_narsese(cmd_in_interval) @@ -234,7 +237,7 @@ def toggle_color() -> None: @cmd_register('readfile', 'read-file') -def read_file(*args: list[str]) -> None: +def read_file(*args: List[str]) -> None: '''Format: readfile [... file path] Call API to read file''' for path in args: @@ -242,7 +245,7 @@ def read_file(*args: list[str]) -> None: @cmd_register('history') -def print_history(*args: list[str]) -> None: +def print_history(*args: List[str]) -> None: '''Format: history [... placeholder] Output the user's input history Default: The Narsese seen at the bottom of the system, not the actual input @@ -252,14 +255,14 @@ def print_history(*args: list[str]) -> None: @cmd_register(('execute', 'exec')) -def exec_code(*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)) @cmd_register(('evaluate', 'eval')) -def eval_code(*args: list[str]) -> None: +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))}') @@ -276,13 +279,13 @@ def toggle_simplify_parse() -> None: @cmd_register('help') -def help(*keywords: list[str], search_in: dict[tuple:tuple] = PRESET_CMDS) -> None: +def help(*keywords: List[str], search_in: Dict[tuple, tuple] = PRESET_CMDS) -> None: '''Format: help [... specific cmd] Display this help document, or assist in retrieving help for additional cmds''' # Core idea: Empty prefix = all cmds keywords = keywords if keywords else [''] # find a matching cmd name - cmd_name_aliases: list[tuple(str)] = prefix_cmd_browse( + cmd_name_aliases: List[tuple(str)] = prefix_cmd_browse( search_in, *keywords) # display "matching cmds" as follows if cmd_name_aliases: @@ -309,16 +312,16 @@ def help(*keywords: list[str], search_in: dict[tuple:tuple] = PRESET_CMDS) -> No # The main functions of each function, and their respective types and roles of parameters and outputs: # 1. macro_def Define macros: Define a macro that contains a set of predefined cmds -# - Parameter: args (list[str]), which contains the macro name and the number of cmds +# - Parameter: args (List[str]), which contains the macro name and the number of cmds # - Output: None # 2. macro_query Query macros: Query defined macros and display their internal commands -# - Argument: args (list[str]), which contains the macro name +# - Argument: args (List[str]), which contains the macro name # - Output: None # 3. macro_exec executes macros by name: Executes macros by name -# - Argument: args (list[str]), which contains the macro name +# - Argument: args (List[str]), which contains the macro name # - Output: None # 4. macro_repeat: Repeat the execution of macros by name and number -# - Parameter: args (list[str]), which contains the macro name and the number of executions +# - Parameter: args (List[str]), which contains the macro name and the number of executions # - Output: None # Externally defined variable types, meanings and relationships: @@ -338,7 +341,7 @@ def help(*keywords: list[str], search_in: dict[tuple:tuple] = PRESET_CMDS) -> No # 11. The help_doc individual cmd depends on the index of PRESET_CMDS ''' -stored_macros: dict[str:list[str]] = {} +stored_macros: Dict[str, List[str]] = {} @cmd_register(('macro-def', 'm-def')) @@ -347,7 +350,7 @@ def macro_def(name: str, num_cmds: int) -> None: According to the number of subsequent input cmds, input a specified line of cmds, you can define an "cmd series" i.e. macro''' # input - cmd_list: list[str] + cmd_list: List[str] if num_cmds: # limited cmd count cmd_list = [ input(f'Please input cmd #{i+1}: ') @@ -367,7 +370,7 @@ def macro_show(name: str): return f'Macro {name}: \n' + \ @cmd_register(('macro-query', 'm-query')) -def macro_query(*args: list[str]) -> None: +def macro_query(*args: List[str]) -> None: '''Format: macro-query [... macro name] 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''' @@ -384,13 +387,13 @@ def macro_query(*args: list[str]) -> None: def macro_exec1(name: str) -> None: '''Execute 1 macro''' - cmds: list[str] = stored_macros[name] + cmds: List[str] = stored_macros[name] for cmd in cmds: execute_input(cmd) @cmd_register(('macro-exec', 'm-exec')) -def macro_exec(*args: list[str]) -> None: +def macro_exec(*args: List[str]) -> None: '''Format: macro-exec [... macro name] Execute macros by name (unlimited number can be stacked) If empty, execute macro "" (empty string)''' @@ -414,7 +417,7 @@ def macro_repeat(name: str, num_executes: int) -> None: 500, 500, silent=False) -reasoners: dict[str:Reasoner] = {'initial': current_NARS_interface} +reasoners: Dict[str, Reasoner] = {'initial': current_NARS_interface} def current_nar_name() -> str: @@ -434,12 +437,12 @@ def reasoner_current() -> None: @cmd_register(('reasoner-list', 'r-list')) -def reasoner_list(*keywords: list[str]) -> None: +def reasoner_list(*keywords: List[str]) -> None: '''Format: reasoner-list [... specific cmd] 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(reasoners, *keywords) + reasoner_names: List[str] = prefix_browse(reasoners, *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 @@ -520,7 +523,7 @@ def random_seed(seed: int) -> None: _parse_need_slash: bool = False -_input_history: list[str] = [] +_input_history: List[str] = [] # Special grammar parser # @@ -576,14 +579,14 @@ def special_narsese_parse(inp: str) -> str: return inp -def execute_input(inp: str, *other_input: list[str]) -> None: +def execute_input(inp: str, *other_input: List[str]) -> None: ''' Main functions: This code is mainly used to process the user input cmds and NAS statements, and perform the corresponding operations according to the input content. The types, meanings and relationships of each variable: - in "input" (str): A string entered by the user, which may be an cmd or a Nax statement. - - cmdHistory "Cmd history" (list[str]): Stores the cmd history entered by the user. + - cmdHistory "Cmd history" (List[str]): Stores the cmd history entered by the user. - parse_need_slash "Escape requires slash" (bool): Indicates whether slashes are required for short escape. - PRESET_CMDS (dict): Index list of preset cmds, used to execute functions based on cmd names. @@ -612,7 +615,7 @@ def execute_input(inp: str, *other_input: list[str]) -> None: # pre-jump cmd if inp.startswith('/'): # the first word is the cmd name, and the following are parameters - words: list[str] = inp[1:].split() + words: List[str] = inp[1:].split() if words: # if not empty cmd_name: str = words[0].lower() # case insensitive auto_execute_cmd_by_name(cmd_name, words[1:]) @@ -629,11 +632,11 @@ def execute_input(inp: str, *other_input: list[str]) -> None: current_NARS_interface.input_narsese(inp) -def auto_execute_cmd_by_name(cmd_name: str, params: list[str], cmd_dict: dict[tuple:tuple] = PRESET_CMDS) -> bool: +def auto_execute_cmd_by_name(cmd_name: str, params: List[str], cmd_dict: Dict[tuple, tuple] = PRESET_CMDS) -> bool: '''Execute cmd by name with autocompletion returns: whether a cmd is chosen and executed successfully''' # auto browse & complete - name_alias_hints: list[tuple[str]] = prefix_cmd_browse(cmd_dict, cmd_name) + name_alias_hints: List[Tuple[str]] = prefix_cmd_browse(cmd_dict, cmd_name) # if it have a precise match, directly use it for i in range(len(name_alias_hints)): name_aliases = name_alias_hints[i] @@ -650,7 +653,7 @@ def auto_execute_cmd_by_name(cmd_name: str, params: list[str], cmd_dict: dict[tu # Cmd execution: Automatically adjust the "parameter requirements" of specific cmds and intercept parameters cmd_data = cmd_dict[name_alias_index] cmd_handler = cmd_data[0] - type_N_default: list[tuple[type, any]] = ( + type_N_default: List[Tuple[type, any]] = ( cmd_data[1] if len(cmd_data) > 1 else None) params: list = quick_convert_cmd_types(params, type_N_default) diff --git a/pynars/Interface.py b/pynars/Interface.py index 131462c..e5311f3 100644 --- a/pynars/Interface.py +++ b/pynars/Interface.py @@ -3,10 +3,12 @@ Principle: Not responsible for "advanced command processing" other than basic command line operations ''' -from typing import Tuple, List, Union from pathlib import Path import argparse # for cmdline +# compatible type annotation +from typing import List, Dict, Tuple, Union + # pynars from pynars.utils.Print import print_out as print_out_origin from pynars.NARS import Reasoner @@ -18,7 +20,7 @@ # utils # -def narsese_parse_safe(narsese: str) -> None | Task: +def narsese_parse_safe(narsese: str) -> Union[None,Task]: ''' Responsible for calling the NAL parser to parse statements @@ -79,7 +81,7 @@ def show_color(self): return NARSInterface.show_color @show_color.setter - def show_color(self, value: bool) -> bool | None: + def show_color(self, value: bool) -> Union[str,bool]: # strictly identify None rather than implicit bool(None) == False if NARSInterface._show_color == None: return None # the color display cannot be enabled @@ -260,7 +262,7 @@ def print_output(self, type: PrintType, content: any, p: float = None, d: float comment_title=comment_title, end=end) - # _event_handlers: list[function] = [] # ! error: name 'function' is not defined + # _event_handlers: List[function] = [] # ! error: name 'function' is not defined _event_handlers: list = [] @property # read only @@ -283,11 +285,11 @@ def _handle_NARS_output(self, out: NARSOutput): print( f'Handler "{handler.__name__}" errors when deal NARS output "{out}": {e}') - def input_narsese(self, lines: str) -> list[NARSOutput]: + def input_narsese(self, lines: str) -> List[NARSOutput]: '''Interfacing with NARS: Injects input provided by an external program into NARS''' return self._handle_lines(lines=lines) - def execute_file(self, path: str | Path) -> None: + def execute_file(self, path: Union[Path,str]) -> None: '''Handle files''' # it's copied directly from Console.py if path is not None: @@ -303,7 +305,7 @@ def execute_file(self, path: str | Path) -> None: # History & Memories # - _input_history: list[str] = [] + _input_history: List[str] = [] @property # readonly def input_history(self): @@ -318,18 +320,18 @@ def input_history(self): INFO : Done. Time-cost: 0.0009992122650146484s. ''' - def _handle_lines(self, lines: str) -> list[NARSOutput]: + def _handle_lines(self, lines: str) -> List[NARSOutput]: ''' Process the input stream of statements, decompose it into multiple statements, and pass each statement to NARS for processing, and finally return the result list of NARS output. Types of parameters and outputs and their effects: - Statement flow: str indicates the input NAL statement flow, which contains multiple NAL statements separated by newlines. - - Returned value: list[NARSOutput], a list of output results after NARS processing, each element is an NARS output object. + - Returned value: List[NARSOutput], a list of output results after NARS processing, each element is an NARS output object. Internal variable types, meanings and mutual relations: - Task List: List[Tuple], which stores information about tasks processed by NARS. Each element is a task row and contains information about multiple tasks. - Task line: Tuple, which contains information about multiple tasks, such as the exported task, modified target, and modified target. - - out Output list: list[NARSOutput], stores NARS output results, each element is an NARS output object. + - out Output list: List[NARSOutput], stores NARS output results, each element is an NARS output object. Main operation process: 1. Decompose the input statement flow into multiple statements. @@ -360,7 +362,7 @@ def _handle_lines(self, lines: str) -> list[NARSOutput]: if task_line is not None: task_list.extend(task_line) - outs: list[NARSOutput] = [] + outs: List[NARSOutput] = [] task_list: List[ Tuple[ @@ -432,7 +434,7 @@ def run_line(self, reasoner: reasoner, line: str): elif line.isdigit(): n_cycles = int(line) self.print_output(PrintType.INFO, f'Run {n_cycles} cycles.') - tasks_in_cycles: list[Task] = [] + tasks_in_cycles: List[Task] = [] # Get all export statements run during this period, deep copy for backup for _ in range(n_cycles): tasks_caught = reasoner.cycle()