### Linking

[
  Datatype links
  Funcon   initialise-linking
  Funcon   link
  Funcon   fresh-link
  Funcon   fresh-initialised-link    Alias fresh-init-link
  Funcon   set-link
  Funcon   follow-if-link
]


Meta-variables
  T <: values


Datatype
  links ::= link(_:variables)


Funcon
  initialise-linking(X:=>T) : =>T
   ~> initialise-storing(X)
/*
  `initialise-linking(X)` ensures that the entities used by the funcons for
  linking are properly initialised.
*/


Funcon
  fresh-link(T) : =>links
    ~> link(allocate-variable(T))


Funcon
  fresh-initialised-link(T, V:T) : =>links
    ~> link(allocate-initialised-variable(T, V))
Alias
  fresh-init-link = fresh-initialised-link


Funcon
  set-link(_:links, _:T) : =>null-type
/*
  The value of a link can be set only once.
*/
Rule
  set-link(link(Var:variables), V:T) ~> initialise-variable(Var, V)


Funcon
  follow-link(_:links) : =>values
Rule
  follow-link(link(Var:variables)) ~> assigned(Var)


Funcon
  follow-if-link(_:values) : =>values
/*
  If `V` is a link, `follow-if-link(V)` computes the set value, and
  otherwise it evaluates to `V`.
*/
Rule
  follow-if-link(link(Var:variables)) ~> assigned(Var)
Rule
  follow-if-link(V:~links) ~> V
