diff options
| -rw-r--r-- | Changelog.md | 20 | ||||
| -rw-r--r-- | Gentle_introduction_Inpla.md | 48 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | sample/245II_new.in | 70 | ||||
| -rw-r--r-- | src/id_table.c | 6 | ||||
| -rw-r--r-- | src/id_table.h | 30 | ||||
| -rw-r--r-- | src/inpla.y | 96 |
7 files changed, 242 insertions, 30 deletions
diff --git a/Changelog.md b/Changelog.md index db1a565..f6cc0dc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,24 @@ # Change log + +### v0.9.1 (released on 28 July 2022) +#### New Features +* **A built-in agent** `Zip`: It takes two lists and returns a list whose elements are pairs of the given two lists elements such that: + ``` + Zip(r,[1,2,...])~[10,20,...] -->* r~[(1,10),(2,20),...]. + ``` + The length of the result will be the same to the shorter one in the given lists: + ``` + Zip(r,[1,2])~[10,20,30,...] -->* r~[(1,10),(2,20)]. + ``` + We can write it with the abbreviation as well: + ``` + >>> r << Zip([1,2,3], [10,20,30]); + (8 interactions, 0.00 sec) + >>> r; free r; + [(1,10),(2,20),(3,30)] + >>> + ``` + ### v0.9.0 (released on 25 July 2022) #### New Features diff --git a/Gentle_introduction_Inpla.md b/Gentle_introduction_Inpla.md index 60c1298..0903a6f 100644 --- a/Gentle_introduction_Inpla.md +++ b/Gentle_introduction_Inpla.md @@ -3,7 +3,11 @@ * [Nets: terms and connections](#nets-terms-and-connections) * [Interaction rules: rewriting rules for nets](#interaction-rules-rewriting-rules-for-nets) - [Example: Operations on unary natural numbers](#example-operations-on-unary-natural-numbers) + - [Abbreviation notation `<<`](#abbreviation-notation-) * [Built-in Agents](#built-in-agents) + - [Tuples](#tuples) + - [Lists](#lists) + - [Built-in rules for tuples and lists](#built-in-rules-for-tuples-and-lists) * [Attributes (integers)](#attributes-integers) - [Built-in anonymous agent for attributes](#built-in-anonymous-agent-for-attributes) - [Arithmetic expressions on attributes](#arithmetic-expressions-on-attributes) @@ -252,7 +256,7 @@ Inpla has built-in agents: * `Nil`, `Cons(x,xs)`, written as `[]` and `x:xs`, respectively. * A nested `Cons` terminated with `Nil` are written as a list notation using brackets `[` and `]`. For instance, `x1 : x2: x3 : Nil` is written as `[x1,x2,x3]` . -#### Built-in rules for tuples and lists +### Built-in rules for tuples and lists There are built-in rules for the same built-in agents that each element is matched and connected such that: @@ -260,17 +264,6 @@ There are built-in rules for the same built-in agents that each element is match (x1,x2)><(y1,y2) => x1~y1, x2~y2 // This is already defined as a built-in rule. ``` -We also have a built-in agent `Append` to append two lists as shown in the following pseudo code: - -``` -Append(r, listB) ~ listA --> r ~ (listA ++ listB) // pseudo code -``` -The order `listB` and `listA` seems something strange, so a special abbreviation notation is prepared: -``` -r << Append(listA, listB) == for == Append(r, listB)~listA -``` - - * Examples of the built-in rules: ``` @@ -291,6 +284,20 @@ r << Append(listA, listB) == for == Append(r, listB)~listA >>> ``` +#### Append a list to the end of another list +We also have a built-in agent `Append` to append a list `listB` to the end of another list `listA` as shown in the following pseudo code: + +``` +Append(r, listB) ~ listA --> r ~ (listA ++ listB) // pseudo code +``` +The order `listB` and `listA` seems something strange, so a special abbreviation notation is prepared: +``` +r << Append(listA, listB) == for == Append(r, listB)~listA +``` + + + + ``` >>> Append(r, [Z, S(Z)]) ~ [A,B,C]; (4 interactions, 0.00 sec) @@ -310,6 +317,23 @@ r << Append(listA, listB) == for == Append(r, listB)~listA >>> ``` +#### `Zip`: It makes two lists into a list of pairs +A built-in agent `Zip` takes two lists and returns a list whose elements are pairs of the given two lists elements such that: +``` +Zip(r,[1,2,...])~[10,20,...] -->* r~[(1,10),(2,20),...]. +``` +The length of the result will be the same to the shorter one in the given lists: +``` +Zip(r,[1,2])~[10,20,30,...] -->* r~[(1,10),(2,20)]. +``` +We can write it with the abbreviation as well: +``` +>>> r << Zip([1,2,3], [10,20,30]); +(8 interactions, 0.00 sec) +>>> r; free r; +[(1,10),(2,20),(3,30)] +>>> +``` ### Eraser @@ -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.9.0, released on **25 July 2022**. (See [Changelog.md](Changelog.md) for details.) +* The current version is 0.9.1, released on **28 July 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.  diff --git a/sample/245II_new.in b/sample/245II_new.in new file mode 100644 index 0000000..2050179 --- /dev/null +++ b/sample/245II_new.in @@ -0,0 +1,70 @@ +// 245II in YALE encoding + +// Rules +Lam(a,b,c) >< App(x,y) => a~x, b~y, c~D; +D >< V => ; +B(a,x,e) >< Lam(b,c,y) => x~Lam(b,c,d), y~DB(a,d,e); +DB(a,b,c) >< V => a~c, b~V; +C(x,y) >< Lam(s,t,u) => + x~Lam(a,b,c), y~Lam(d,e,f), + s~Delta(a,d), t~Delta(b,e), u~C(c,f); +C(x,y) >< V => x~V, y~V; +Delta(x,y) >< Delta(a,b) => x~a, y~b; +B(x,a,b) >< Delta(c,d) => x~CB(a,b,Delta(c,d)); +Delta(a,b) >< CB(x,y,z) => + x~Delta(c,d), y~Delta(e,f), z~Delta(B(a,c,e),B(b,d,f)); +Delta(x,y) >< V => x~V, y~V; +Delta(x,y) >< C(t,s) => + x~C(a,b), y~C(c,d), t~Delta(b,d), s~Delta(a,c); +Delta(x,y) >< App(t,s) => + x~App(a,b), y~App(c,d), t~Delta(a,c), s~Delta(b,d); +Delta(x,y) >< Lam(t,s,u)=> + x~Lam(a,b,c), y~Lam(d,e,f), + t~Delta(a,d), s~Delta(b,e), u~Delta(c,f); +DB(x,y,z) >< CB(t,s,u) => + x~CB(d,e,u), y~CB(t,f,d), s~DB(e,f,z); +C(x,y) >< CB(t,s,u) => + x~CB(a,b,c), y~CB(d,e,f), + t~Delta(a,d), s~C(b,e), u~C(c,f); +D >< CB(a,b,c) => a~c, b~D; + +Eps >< Eps => ; +Eps >< S(x) => x~Eps; +Eps >< V => ; +Eps >< D =>; +Eps >< Delta(t,s) => t~Eps,s~Eps; +Eps >< Lam(t,s,u) => t~Eps,s~Eps,u~Eps; +Eps >< App(t,s) => t~Eps,s~Eps; +Eps >< B(t,s,u) => t~Eps,s~Eps,u~Eps; +Eps >< CB(t,s,u) => t~Eps,s~Eps,u~Eps; + + +// Nets +// lam x.x +new(r) >< Id => r~Lam(i,i,V); + +// lam f. lam x. f(fx) +new(r) >< Two => r~Lam(Lam(a,b,c),B(c,C(App(a,d),App(d,b)),V),V); + +// lam f. lam x. f(fx) +new(r) >< Four => r~Lam(Lam(a,b,c), B(c,C(App(a,d), C(App(d, e), C(App(e, f), App(f, b)))), V), V); + +// lam f. lam x. f(fx) +new(r) >< Five => r~Lam(Lam(a, b, c), B(c, C(App(a, d), C(App(d, e), C(App(e,f), C(App(f, g), App(g, b))))), V), V); + + +// instances +id1 << new(Id); +id2 << new(Id); +two << new(Two); +four << new(Four); +five << new(Five); + + +// 245II +two ~ App(aux1, four); +aux1 ~ App(aux2, five); +aux2 ~ App(aux3, id1); +aux3 ~ App(aux4, id2); +aux4; +exit; diff --git a/src/id_table.c b/src/id_table.c index 07706f9..2ad96ad 100644 --- a/src/id_table.c +++ b/src/id_table.c @@ -39,6 +39,8 @@ void IdTable_init() { IdTable[ID_INTAGENT].aux.arity = 1; IdTable[ID_APPEND].aux.arity = 2; + IdTable[ID_ZIP].aux.arity = 2; + IdTable[ID_ZIPC].aux.arity = 2; IdTable[ID_MERGER].aux.arity = 1; IdTable[ID_MERGER_P].aux.arity = 1; IdTable[ID_ADD].aux.arity = 2; @@ -69,6 +71,8 @@ void IdTable_init() { IdTable[ID_INTAGENT].name = "Int"; IdTable[ID_APPEND].name = "Append"; + IdTable[ID_ZIP].name = "Zip"; + IdTable[ID_ZIPC].name = "ZipC"; IdTable[ID_MERGER].name = "Merger"; IdTable[ID_MERGER_P].name = "_MergerP"; IdTable[ID_ADD].name = "Add"; @@ -111,6 +115,8 @@ int IdTable_getid_builtin_funcAgent(Ast *agent) { id = ID_MOD; } else if (strcmp((char *)agent->left->sym, "Append") == 0) { id = ID_APPEND; + } else if (strcmp((char *)agent->left->sym, "Zip") == 0) { + id = ID_ZIP; } else if (strcmp((char *)agent->left->sym, "Int") == 0) { id = ID_INTAGENT; } else if (strcmp((char *)agent->left->sym, "Merger") == 0) { diff --git a/src/id_table.h b/src/id_table.h index 152b028..7ee04bc 100644 --- a/src/id_table.h +++ b/src/id_table.h @@ -36,20 +36,22 @@ #define START_ID_OF_BUILTIN_OP_AGENT 15 #define ID_APPEND 15 -#define ID_MERGER 16 -#define ID_MERGER_P 17 -#define ID_ADD 18 -#define ID_ADD2 19 -#define ID_SUB 20 -#define ID_SUB2 21 -#define ID_MUL 22 -#define ID_MUL2 23 -#define ID_DIV 24 -#define ID_DIV2 25 -#define ID_MOD 26 -#define ID_MOD2 27 -#define ID_PERCENT 28 -#define END_ID_OF_BUILTIN_OP_AGENT 28 +#define ID_ZIP 16 +#define ID_ZIPC 17 +#define ID_MERGER 18 +#define ID_MERGER_P 19 +#define ID_ADD 20 +#define ID_ADD2 21 +#define ID_SUB 22 +#define ID_SUB2 23 +#define ID_MUL 24 +#define ID_MUL2 25 +#define ID_DIV 26 +#define ID_DIV2 27 +#define ID_MOD 28 +#define ID_MOD2 29 +#define ID_PERCENT 30 +#define END_ID_OF_BUILTIN_OP_AGENT 30 // ID_ERASER and ID_DUP was put as 254, 255 // because these IDs are wanted larger like ID_DUP > any_agent.id diff --git a/src/inpla.y b/src/inpla.y index b7243d0..182bed7 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -22,8 +22,8 @@ // ---------------------------------------------- -#define VERSION "0.9.0" -#define BUILT_DATE "25 July 2022" +#define VERSION "0.9.1" +#define BUILT_DATE "28 July 2022" // ------------------------------------------------------------------ @@ -9526,7 +9526,7 @@ loop_agent_a1_a2_this_order: case ID_CONS: { - // App(r,a) >< [x|xs] => r~(*R)[x|w], (*L)App(w,a)~xs; + // App(r,a) >< x:xs => r~(*R)x:w, (*L)App(w,a)~xs; COUNTUP_INTERACTION(vm); VALUE a1p0 = AGENT(a1)->port[0]; @@ -9545,6 +9545,96 @@ loop_agent_a1_a2_this_order: break; // end ID_APPEND + + case ID_ZIP: + switch (BASIC(a2)->id) { + case ID_NIL: + { + // Zip(r, blist) >< [] => r~[], blist~Eraser; + COUNTUP_INTERACTION(vm); + + VALUE a1p0 = AGENT(a1)->port[0]; + VALUE a1p1 = AGENT(a1)->port[1]; + + // Eraser + BASIC(a1)->id = ID_ERASER; + PUSH(vm, a1p1, a1); + + a1=a1p0; + goto loop; + } + + case ID_CONS: + { + // Zip(r, blist) >< x:xs => Zip_Cons(r,x:xs)~blist; + COUNTUP_INTERACTION(vm); + + VALUE a1p1 = AGENT(a1)->port[1]; + + BASIC(a1)->id = ID_ZIPC; + AGENT(a1)->port[1] = a2; + a2 = a1p1; + goto loop; + } + } + + break; // end ID_ZIP + + case ID_ZIPC: + switch (BASIC(a2)->id) { + case ID_NIL: + { + // Zip_Cons(r, x:xs)><[] => r~[], x:xs~Eraser; + COUNTUP_INTERACTION(vm); + + VALUE a1p0 = AGENT(a1)->port[0]; + VALUE a1p1 = AGENT(a1)->port[1]; + + // Eraser + BASIC(a1)->id = ID_ERASER; + PUSH(vm, a1p1, a1); + + a1=a1p0; + goto loop; + } + + case ID_CONS: + { + // Zip_Cons(r, (*1)x:xs) >< y:ys => + // r~(*R)((*1)(y,x):ws), (*L)Zip(ws,ys)~xs; + COUNTUP_INTERACTION(vm); + + VALUE r = AGENT(a1)->port[0]; + VALUE inner_cons = AGENT(a1)->port[1]; + VALUE xs = AGENT(inner_cons)->port[1]; + VALUE ys = AGENT(a2)->port[1]; + + // (*1)(y,x) + BASIC(inner_cons)->id = ID_TUPLE2; + VALUE x = AGENT(inner_cons)->port[0]; + VALUE y = AGENT(a2)->port[0]; + AGENT(inner_cons)->port[0] = y; + AGENT(inner_cons)->port[1] = x; + + // (*R)((*1)(y,x):ws) + VALUE ws = make_Name(vm); + AGENT(a2)->port[0] = inner_cons; + AGENT(a2)->port[1] = ws; + + PUSH(vm, r, a2); + + // (*L)Zip(ws,ys)~xs; + BASIC(a1)->id = ID_ZIP; + AGENT(a1)->port[0] = ws; + AGENT(a1)->port[1] = ys; + a2 = xs; + goto loop; + } + } + + break; // end ID_ZIPC + + case ID_MERGER: switch (BASIC(a2)->id) { |
