DrRuisseau / interact

Interaction net / combinator language based on https://core.ac.uk/download/pdf/81113716.pdf

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Language and interpreter for interaction nets

The interpreter implements interaction nets and combinators as defined in https://core.ac.uk/download/pdf/81113716.pdf.

Running

Launch sbt and then runMain Main example.in in the sbt shell to process example.in.

Language

There are 3 basic statements: cons defines a constructor (with associated rules), rule defines a detached rule, and let creates a part of the net that should be evaluated. Comments start with # and extend until the end of the line. There are no statement separators and no significant whitespace.

Constructors

Constructors are written as Id(aux_1, aux_2, ..., aux_n). The parentheses are optional for arity 0. For example:

# Church numerals
cons Z
cons S(n)

Since every constructor has a principal port there is no need to name it, but it can be done for documentation purposes using "cut" syntax:

cons Z . result
cons S(n) . result

Nets

The nets that should be reduced by the interpreter are defined using let clauses:

let two, example_3_plus_5 =
  two . S(S(Z)),
  y . S(S(S(S(S(Z))))),
  x . S(S(S(Z))),
  Add(y, example_3_plus_5) . x

The body of the let clause is a list of cuts (a . b where a and b are expressions that are connected via their principal ports). The basic expressions are identifiers (for nullary constructors (usually capitalized), free ports, or local wires) or applications of constructors (which connect the principal port of an argument to an auxiliary port of the constructor). Local wires may be introduced in a let clause (x and y in the previous snippet). They must be used in a linear way, i.e. they occur exactly twice in the clause. The left-hand side of the let clause lists its free ports (two and example_3_plus_5 in the previous snippet). They must be used exactly once in the body. Note that cuts are always symmetric, i.e. a . b is the same as b . a.

Rules

All rules are defined on a cut. Detached rules use a cut pattern that names the ports on the left-hand side and has a list of cuts as the replacement on the right-hand side:

rule Dup(a, b) . Z  = a . Z, b . Z
rule Dup(a, b) . S(x) = x . Dup(sa, sb),
                        a . S(sa), b . S(sb)

All port names in the pattern must be unique, and their use across the combination of the pattern and the replacement must be linear (i.e. they are treated as free ports in the replacement). Like in let clauses, the replacement may introduce local wires.

Rules can be defined in a simpler way together with one of their constructors using a cut clause. This avoids repeating the constructor name and assigning names to the ports in a pattern match. Instead the auxiliary ports use the names defined in the constructor:

cons Dup(a, b)
  cut Z  = a . Z, b . Z
  cut S(x) = x . Dup(sa, sb), a . S(sa), b . S(sb)

Rule derivation

Rules that reduce a cut between a constructor and the standard Erase and Dup constructors can be derived automatically using a deriving clause:

cons Add(y, r) . x
  deriving Erase, Dup

The above example is equivalent to:

cons Add(y, r) . x
  cut Erase = y . Erase, r . Erase
  cut Dup(a, b) = a . Add(s2, s3),
                  b . Add(s4, s5),
                  y . Dup(s2, s4),
                  r . Dup(s3, s5)

Note that this expansion is purely syntactical. You still need to define suitable Dup and Erase constructors by yourself, e.g.:

cons Erase                   deriving Erase
cons Dup(a, b) . in          deriving Erase
  cut Dup(c, d) = a . c, b . d

Church numerals

There is syntactic support for parsing and printing church numerals, e.g.:

let example_3_times_2 =
  Mult(2'c, example_3_times_2) . 3'c

The snippet expands to:

let example_3_times_2 =
  Mult(S(S(Z)), example_3_times_2) . S(S(S(Z)))

This assumes that you have suitable definitions of Z and S like:

cons Z                       deriving Erase, Dup
cons S(n)                    deriving Erase, Dup

Lists

There is syntactic support for parsing and printing lists, e.g.:

let list_1_2_3 =
  1'c :: 2'c :: 3'c :: Nil

The snippet expands to:

let list_1_2_3 =
  Cons(1'c, Cons(2'c, Cons(3'c, Nil)))

This assumes that you have a suitable definitions of Cons like:

cons Nil                     deriving Erase, Dup
cons Cons(head, tail) . l    deriving Erase, Dup

About

Interaction net / combinator language based on https://core.ac.uk/download/pdf/81113716.pdf


Languages

Language:Scala 100.0%