diff options
| author | Shinya Sato <shinnya.sato@gmail.com> | 2022-12-22 12:48:24 +0900 |
|---|---|---|
| committer | Shinya Sato <shinnya.sato@gmail.com> | 2022-12-22 12:48:24 +0900 |
| commit | d2304c259e164f90564e9ff96ce9caba09c802b0 (patch) | |
| tree | ea57a54ea32719da42176f7f3d0ffadd3c77a336 | |
| parent | caedc249ed3685f5165f3c7be3c353b46ff15470 (diff) | |
| parent | da4f4c819693599582610ca6b5fe8a653dfa0eb4 (diff) | |
| download | inpla-d2304c259e164f90564e9ff96ce9caba09c802b0.tar.gz inpla-d2304c259e164f90564e9ff96ce9caba09c802b0.zip | |
Merge branch 'develop'
Diffstat (limited to '')
| -rw-r--r-- | Changelog.md | 32 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | src/ast.h | 2 | ||||
| -rw-r--r-- | src/config.h | 4 | ||||
| -rw-r--r-- | src/inpla.y | 200 |
5 files changed, 178 insertions, 62 deletions
diff --git a/Changelog.md b/Changelog.md index b47230d..5a4c5ff 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,35 @@ # Change log +### v0.10.1 (released on 22 December 2022) +#### Polished +* **Warning messages**: Inpla puts warning messages when names are connected to expressions because Runtime Error can be caused. In addition, messages are put when names are included in expressions as well. In future, those will be detected by a type inference system, not such ad hoc finding, I hope. + + ``` + >>> A(r)><B(int x) => r~1, x~100; + Warning: The variable 'x' is connected to an expression. It may cause runtime error. + ``` + + ``` + >>> A(r, y)><B(int x) => r~(x+y); + Warning: The agent 'A' has been already defined as whose arity is 1, but now used as the arity is 2. + Warning: 'y' is used as a variable on properties, though it is not so... + ``` + + ``` + >>> A(r, y)><B(int x) + ... | y==0 => r~x, y~x + ... | _ => r~x+1, y~x; + Warning: 'y' is used as a variable on properties, though it is not so... + ``` +#### Minor change +* **Messages of applying Tail Call Optimisation** : A message was put when the optimisation is applied, but now it turns off because this is for developers. To change it on, make the following line uncommented in `config.h`: + + ``` + //#define VERBOSE_TCO // Put message when TCO is enable. + ``` + + + ### v0.10.0 (released on 17 September 2022) #### Polished (inner) * **New instruction set for reuse active pairs**: Inpla supports annotations to reuse active active pairs by putting (\*L) and (\*R) in front of agents in rules as an experiment option. It was just to reuse only nodes for active pairs, but now we can specify the reuse method in the level of ports. As an example, we take the following rule: @@ -21,7 +51,7 @@ 1: PUSH var11 var12 2: RET ``` - It becomes quite reasonable, but there is no significant improvement in terms of execution speed than I expected. It is useful to demonstrate the execution performance obtained by the theoretical analysis. + It becomes quite reasonable, but there is no significant improvement in terms of execution speed than I expected. It becomes useful to demonstrate the execution performance obtained by the theoretical analysis. To keep using the old version, make the following uncommented in `config.h`: @@ -6,7 +6,7 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you write programs for sequential execution, it works also in multi-threaded parallel execution. Each thread is managed on each CPU-core with POSIX-thread library. -* The current version is 0.10.0, released on **17 September 2022**. (See [Changelog.md](Changelog.md) for details.) +* The current version is 0.10.1 (minor update), released on **22 December 2022**. (See [Changelog.md](Changelog.md) for details.) * The below graph shows speed-up ratio to threads numbers for programs in the following benchmark table.  @@ -5,7 +5,7 @@ typedef enum { AST_SYM=0, AST_NAME, AST_INTVAR, AST_AGENT, - AST_CNCT, AST_CNCT_TRO_INTVAR, AST_CNCT_TRO_CONS, AST_CNCT_TRO, + AST_CNCT, AST_CNCT_TCO_INTVAR, AST_CNCT_TCO_CONS, AST_CNCT_TCO, AST_RULE, AST_BODY, AST_IF, AST_THEN_ELSE, // this is for ASTLIST diff --git a/src/config.h b/src/config.h index 83ba616..811f2e4 100644 --- a/src/config.h +++ b/src/config.h @@ -73,7 +73,7 @@ // // Optimisation inspired by Tail Recursion Optimisation // -#define OPTIMISE_IMCODE_TRO +#define OPTIMISE_IMCODE_TCO // // Optimisation of the intermediate codes @@ -124,7 +124,7 @@ //#define VERBOSE_NODE_USE // Put memory usage of agents and names. //#define VERBOSE_HOOP_EXPANSION // Put messages when hoops are expanded. //#define VERBOSE_EQSTACK_EXPANSION // Put messages when Eqstacks are expanded. -//#define VERBOSE_TRO // Put message when TRO is enable. +//#define VERBOSE_TCO // Put message when TCO is enable. diff --git a/src/inpla.y b/src/inpla.y index 7f960e6..dbac76c 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -22,8 +22,8 @@ // ---------------------------------------------- -#define VERSION "0.10.0" -#define BUILT_DATE "17 September 2022" +#define VERSION "0.10.1" +#define BUILT_DATE "22 December 2022" // ------------------------------------------------------------------ @@ -3297,6 +3297,10 @@ typedef struct { int jmpcnctBlockRegState[VM_REG_SIZE]; int is_in_jmpcnctBlock; #endif + + + // warning output for x:int~y:int and x:int~1 + int put_warning_for_cnct_property; } CmEnvironment; @@ -3305,9 +3309,12 @@ typedef struct { #define ANNOTATE_NOTHING 0 // The rule agent is not reused. #define ANNOTATE_REUSE 1 // Annotation (*L), (*R) is specified. #define ANNOTATE_INT_MODIFIER 2 // (int i), therefore it must not be freed. -#define ANNOTATE_TRO 3 // Annotated and reused as TRO. +#define ANNOTATE_TCO 3 // Annotated and reused as TCO. -static CmEnvironment CmEnv; +// Init for CmEnv +static CmEnvironment CmEnv = { + .put_warning_for_cnct_property = 1, // with warning +}; static inline @@ -3384,6 +3391,7 @@ void CmEnv_clear_all(void) // reset the register assignment table CmEnv_clear_register_assignment_table_all(); + } void CmEnv_clear_keeping_rule_properties(void) @@ -3497,11 +3505,11 @@ int CmEnv_find_var(char *key) { for (i=0; i<CmEnv.bindPtr; i++) { if (strcmp(key, CmEnv.bind[i].name) == 0) { -#ifndef OPTIMISE_IMCODE_TRO +#ifndef OPTIMISE_IMCODE_TCO CmEnv.bind[i].refnum++; #else - // During compilation on ANNOTATE_TRO, ignore counting up. - if (CmEnv.annotateL != ANNOTATE_TRO) { + // During compilation on ANNOTATE_TCO, ignore counting up. + if (CmEnv.annotateL != ANNOTATE_TCO) { CmEnv.bind[i].refnum++; } #endif @@ -5821,7 +5829,7 @@ void Ast_remove_tuple1_in_mainbody(Ast *mainbody) { } -void Ast_undo_TRO_annotation(Ast *mainbody) { +void Ast_undo_TCO_annotation(Ast *mainbody) { // Make any kinds of CNCTs changed into just AST_CNCT // in order to give it to compilation procedures safely. @@ -5857,17 +5865,17 @@ void Ast_undo_TRO_annotation(Ast *mainbody) { Ast *then_branch = if_sentence->right->left; Ast *else_branch = if_sentence->right->right; - Ast_undo_TRO_annotation(then_branch); - Ast_undo_TRO_annotation(else_branch); + Ast_undo_TCO_annotation(then_branch); + Ast_undo_TCO_annotation(else_branch); } } -int Ast_make_annotation_TailRecursionOptimisation(Ast *mainbody) { +int Ast_make_annotation_TailCallOptimisation(Ast *mainbody) { // Return 1 when annotated. // - // When there is an equation for TRO, its ID is changed from AST_CNCT into - // AST_CNCT_TRO_INTVAR or AST_CNCT_TRO. + // When there is an equation for TCO, its ID is changed from AST_CNCT into + // AST_CNCT_TCO_INTVAR or AST_CNCT_TCO. if (mainbody == NULL) @@ -5905,8 +5913,8 @@ int Ast_make_annotation_TailRecursionOptimisation(Ast *mainbody) { int idL = CmEnv.idL; - int available_TRO = 0; - AST_ID astID_of_TRO; // = idL; // idL is dummy + int available_TCO = 0; + AST_ID astID_of_TCO; // = idL; // idL is dummy // --- recursion_agent ~ constructor_agent if ((recursion_agent->left->id == AST_SYM) && @@ -5915,8 +5923,8 @@ int Ast_make_annotation_TailRecursionOptimisation(Ast *mainbody) { if (Ast_is_expr(constructor_agent)) { // --- CASE 1: rule_left_agent ~ expression - available_TRO = 1; - astID_of_TRO = AST_CNCT_TRO_INTVAR; + available_TCO = 1; + astID_of_TCO = AST_CNCT_TCO_INTVAR; } else if (constructor_agent->id == AST_NAME) { // --- CASE 2: rule_left_agent ~ name where the name is meta_R @@ -5926,8 +5934,8 @@ int Ast_make_annotation_TailRecursionOptimisation(Ast *mainbody) { if ((exists_in_table) && ((type == NB_META_R) || (type == NB_META_L))) { - available_TRO = 1; - astID_of_TRO = AST_CNCT_TRO; + available_TCO = 1; + astID_of_TCO = AST_CNCT_TCO; } } @@ -5936,11 +5944,11 @@ int Ast_make_annotation_TailRecursionOptimisation(Ast *mainbody) { - if (available_TRO) { + if (available_TCO) { // puts("Target:"); - // ast_puts(eq_TRO); puts(""); + // ast_puts(eq_TCO); puts(""); - eq->id = astID_of_TRO; + eq->id = astID_of_TCO; // Foo ==> (*L)Foo Ast *annotationL = ast_makeAST(AST_ANNOTATION_L, recursion_agent, NULL); @@ -5962,8 +5970,8 @@ int Ast_make_annotation_TailRecursionOptimisation(Ast *mainbody) { Ast *else_branch = if_sentence->right->right; int ret_status = 0; - ret_status += Ast_make_annotation_TailRecursionOptimisation(then_branch); - ret_status += Ast_make_annotation_TailRecursionOptimisation(else_branch); + ret_status += Ast_make_annotation_TailCallOptimisation(then_branch); + ret_status += Ast_make_annotation_TailCallOptimisation(else_branch); if (ret_status == 0) { return 0; @@ -5996,7 +6004,19 @@ int Compile_expr_on_ast(Ast *ptr, int target) { ptr->left->sym); return 0; } - + + // Check for x:int + if (CmEnv.put_warning_for_cnct_property) { + NB_TYPE type; + int get_result; + get_result = CmEnv_gettype_forname((ptr)->left->sym, &type); + if ((get_result) && (type != NB_INTVAR)) { + printf("Warning: '%s' is used as a variable on properties, though it is not so...\n", + (ptr)->left->sym); + + } + } + IMCode_genCode2(OP_LOAD, result, target); return 1; break; @@ -6642,7 +6662,7 @@ int check_invalid_occurrence(Ast *ast) { void Compile_gen_RET_for_rulebody(void) { - if (CmEnv.annotateL == ANNOTATE_TRO) { + if (CmEnv.annotateL == ANNOTATE_TCO) { return; } @@ -6679,19 +6699,79 @@ void Compile_gen_RET_for_rulebody(void) { int Compile_eqlist_on_ast(Ast *at) { - - while (at!=NULL) { - Ast *eq = at->left; - if (!check_invalid_occurrence_as_rule(eq->left) || - !check_invalid_occurrence_as_rule(eq->right)) { - return 0; + NB_TYPE type; + Ast *at_preserved = at; + + + // Occurrence check + if (CmEnv.put_warning_for_cnct_property) { + while (at!=NULL) { + Ast *eq = at->left; + + // It does not work for now + if (!check_invalid_occurrence_as_rule(eq->left) || + !check_invalid_occurrence_as_rule(eq->right)) { + return 0; + } + + // Check for: x:int~expr + if ((eq->left)->id == AST_NAME) { + int result = CmEnv_gettype_forname((eq->left)->left->sym, &type); + if ((result != 0) && (type == NB_INTVAR)) { + // the left term is a variable on property + + if (Ast_is_expr(eq->right)) { + printf("Warning: The variable '%s' is connected to an expression. It may cause runtime error.\n", + (eq->left)->left->sym); + + } else if ((eq->right)->id == AST_NAME) { + result = CmEnv_gettype_forname((eq->right)->left->sym, &type); + if ((result !=0) && (type == NB_INTVAR)) { + printf("Warning: The variable '%s' is connected to a variable %s. It may cause runtime error.\n", + (eq->left)->left->sym, (eq->right)->left->sym); + } + } + } + } + + // Check for: expr~x:int + if ((eq->right)->id == AST_NAME) { + int result = CmEnv_gettype_forname((eq->right)->left->sym, &type); + if ((result != 0) && (type == NB_INTVAR)) { + // the right term is a variable on property + + if (Ast_is_expr(eq->left)) { + printf("Warning: The variable '%s' is connected to an expression. It may cause runtime error.\n", + (eq->right)->left->sym); + + } else { + if ((eq->left)->id == AST_NAME) { + result = CmEnv_gettype_forname((eq->left)->left->sym, &type); + if ((result !=0) && (type == NB_INTVAR)) { + printf("Warning: The variable '%s' is connected to a variable %s. It may cause runtime error.\n", + (eq->right)->left->sym, (eq->left)->left->sym); + + } + } + } + } + } + + at = ast_getTail(at); } + } + + at = at_preserved; + + + while (at!=NULL) { + Ast *eq = at->left; Ast *next = ast_getTail(at); -#ifndef OPTIMISE_IMCODE_TRO - // Without Tail Rcursion Optimisation +#ifndef OPTIMISE_IMCODE_TCO + // Without Tail Call Recursion Optimisation // 2021/9/6: It seems, always EnvAddCodePUSH is selected // because at is not NULL in this step. Should be (next == NULL)? @@ -6717,7 +6797,7 @@ int Compile_eqlist_on_ast(Ast *at) { #else - // WITH Tail Rcursion Optimisation + // WITH Tail Call Optimisation if ((next != NULL) || ((next == NULL) && (eq->id == AST_CNCT))) { @@ -6729,7 +6809,7 @@ int Compile_eqlist_on_ast(Ast *at) { // operation for the last placed equation. - if (eq->id == AST_CNCT_TRO_INTVAR) { + if (eq->id == AST_CNCT_TCO_INTVAR) { // rule_left_agent ~ expression // It always becomes loop operation @@ -6743,7 +6823,7 @@ int Compile_eqlist_on_ast(Ast *at) { int arity = 0; // The `rule_left_aget' is annotated by (*L) manually - // in the function `Ast_make_annotation_TailRecursionOptimisation'. + // in the function `Ast_make_annotation_TailCallOptimisation'. // So, first // Pealing (*L) @@ -6752,7 +6832,7 @@ int Compile_eqlist_on_ast(Ast *at) { Ast *arg_list = deconst_term->right; // arglist - // printf("TRO: %s><int\n", deconst_term->left->sym); + // printf("TCO: %s><int\n", deconst_term->left->sym); for (int i=0; i<MAX_PORT; i++) { @@ -6795,14 +6875,14 @@ int Compile_eqlist_on_ast(Ast *at) { IMCode_genCode0(OP_LOOP); // prevent putting FREE_L, and ignore counting up for name ref - CmEnv.annotateL = ANNOTATE_TRO; + CmEnv.annotateL = ANNOTATE_TCO; // IMCode_puts(0); exit(1); - } else if (eq->id == AST_CNCT_TRO) { + } else if (eq->id == AST_CNCT_TCO) { // rule_left_agent ~ name where the name is meta_R // Pealing (*L) @@ -6837,7 +6917,7 @@ int Compile_eqlist_on_ast(Ast *at) { // From now on, // prevent putting FREE_L, and ignore counting up for name ref - CmEnv.annotateL = ANNOTATE_TRO; + CmEnv.annotateL = ANNOTATE_TCO; #ifdef OPTIMISE_TWO_ADDRESS IMCode_genCode0(OP_BEGIN_JMPCNCT_BLOCK); @@ -7085,7 +7165,7 @@ int Compile_rule_mainbody_on_ast(Ast *mainbody) { // Compilation of Guard expressions int newreg = CmEnv_newvar(); - if (!Compile_expr_on_ast(guard, newreg)) return -1; + if (!Compile_expr_on_ast(guard, newreg)) return 0; #ifdef OPTIMISE_IMCODE @@ -7661,8 +7741,8 @@ int make_rule_oneway(Ast *ast) { - CmEnv_clear_all(); - + CmEnv_clear_all(); + if (idL == ID_INT) { set_metaL_as_IntName(ruleAgent_L); CmEnv.annotateL = ANNOTATE_INT_MODIFIER; // to prevent putting Free_L @@ -7688,22 +7768,22 @@ int make_rule_oneway(Ast *ast) { //puts("Before:"); ast_puts(rule_mainbody); puts(""); -#ifdef OPTIMISE_IMCODE_TRO +#ifdef OPTIMISE_IMCODE_TCO - int is_tro; + int is_tco; if (!Ast_mainbody_has_agentID(rule_mainbody, AST_ANNOTATION_L)) { - is_tro = Ast_make_annotation_TailRecursionOptimisation(rule_mainbody); + is_tco = Ast_make_annotation_TailCallOptimisation(rule_mainbody); } else { - is_tro = 0; + is_tco = 0; } -#ifdef VERBOSE_TRO - if (is_tro) { - printf("=== TRO is applied to "); +#ifdef VERBOSE_TCO + if (is_tco) { + printf("=== Tail Call Optimisation is applied to "); printf("Rule: %s(id:%d) >< %s(id:%d). ===\n", IdTable_get_name(idL), idL, IdTable_get_name(idR), idR); @@ -7719,12 +7799,12 @@ int make_rule_oneway(Ast *ast) { -#ifdef OPTIMISE_IMCODE_TRO - if (is_tro) { +#ifdef OPTIMISE_IMCODE_TCO + if (is_tco) { // puts("Before:"); ast_puts(rule_mainbody); puts(""); - Ast_undo_TRO_annotation(rule_mainbody); + Ast_undo_TCO_annotation(rule_mainbody); // puts("After:"); ast_puts(rule_mainbody); puts(""); @@ -7737,7 +7817,7 @@ int make_rule_oneway(Ast *ast) { gencode_num += CmEnv_generate_VMCode(&code[2]); #else - //int here_flag = is_tro; + //int here_flag = is_tco; int here_flag = 1; if (here_flag) { puts("[1]. --- RAW codes --------------------------------"); @@ -7861,16 +7941,22 @@ int make_rule(Ast *ast) { // another way + CmEnv.put_warning_for_cnct_property = 0; // without warning + + ruleAgent_L = ast->left->left; ruleAgent_R = ast->left->right; ast->left->left = ruleAgent_R; ast->left->right = ruleAgent_L;; set_annotation_LR(VM_OFFSET_ANNOTATE_R, VM_OFFSET_ANNOTATE_L); - // ast_puts(ast);puts(""); - return make_rule_oneway(ast); + int result_make_rule = make_rule_oneway(ast); + + CmEnv.put_warning_for_cnct_property = 1; // retrieve warning + + return result_make_rule; } |
