init commit again
This commit is contained in:
269
IBAF-cbs/Funcons-beta/Computations/Normal/Binding/Binding.cbs
Normal file
269
IBAF-cbs/Funcons-beta/Computations/Normal/Binding/Binding.cbs
Normal file
@@ -0,0 +1,269 @@
|
||||
### Binding
|
||||
|
||||
[
|
||||
Type environments Alias envs
|
||||
Datatype identifiers Alias ids
|
||||
Funcon identifier-tagged Alias id-tagged
|
||||
Funcon fresh-identifier
|
||||
Entity environment Alias env
|
||||
Funcon initialise-binding
|
||||
Funcon bind-value Alias bind
|
||||
Funcon unbind
|
||||
Funcon bound-directly
|
||||
Funcon bound-value Alias bound
|
||||
Funcon closed
|
||||
Funcon scope
|
||||
Funcon accumulate
|
||||
Funcon collateral
|
||||
Funcon bind-recursively
|
||||
Funcon recursive
|
||||
]
|
||||
|
||||
|
||||
Meta-variables
|
||||
T <: values
|
||||
|
||||
|
||||
#### Environments
|
||||
|
||||
Type
|
||||
environments ~> maps(identifiers, values?)
|
||||
Alias
|
||||
envs = environments
|
||||
/*
|
||||
An environment represents bindings of identifiers to values.
|
||||
Mapping an identifier to `( )` represents that its binding is hidden.
|
||||
|
||||
Circularity in environments (due to recursive bindings) is represented using
|
||||
bindings to cut-points called `links`. Funcons are provided for making
|
||||
declarations recursive and for referring to bound values without explicit
|
||||
mention of links, so their existence can generally be ignored.
|
||||
*/
|
||||
|
||||
|
||||
Datatype
|
||||
identifiers ::= {_:strings} | identifier-tagged(_:identifiers, _:values)
|
||||
Alias
|
||||
ids = identifiers
|
||||
Alias
|
||||
id-tagged = identifier-tagged
|
||||
/*
|
||||
An identifier is either a string of characters, or an identifier tagged with
|
||||
some value (e.g., with the identifier of a namespace).
|
||||
*/
|
||||
|
||||
|
||||
Funcon
|
||||
fresh-identifier : =>identifiers
|
||||
/*
|
||||
`fresh-identifier` computes an identifier distinct from all previously
|
||||
computed identifiers.
|
||||
*/
|
||||
Rule
|
||||
fresh-identifier ~> identifier-tagged("generated", fresh-atom)
|
||||
|
||||
|
||||
#### Current bindings
|
||||
|
||||
Entity
|
||||
environment(_:environments) |- _ ---> _
|
||||
Alias
|
||||
env = environment
|
||||
/*
|
||||
The environment entity allows a computation to refer to the current bindings
|
||||
of identifiers to values.
|
||||
*/
|
||||
|
||||
|
||||
Funcon
|
||||
initialise-binding(X:=>T) : =>T
|
||||
~> initialise-linking(initialise-generating(closed(X)))
|
||||
/*
|
||||
`initialise-binding(X)` ensures that `X` does not depend on non-local bindings.
|
||||
It also ensures that the linking entity (used to represent potentially cyclic
|
||||
bindings) and the generating entity (for creating fresh identifiers) are
|
||||
initialised.
|
||||
*/
|
||||
|
||||
|
||||
Funcon
|
||||
bind-value(I:identifiers, V:values) : =>environments
|
||||
~> { I |-> V }
|
||||
Alias
|
||||
bind = bind-value
|
||||
/*
|
||||
`bind-value(I, X)` computes the environment that binds only `I` to the value
|
||||
computed by `X`.
|
||||
*/
|
||||
|
||||
|
||||
Funcon
|
||||
unbind(I:identifiers) : =>environments
|
||||
~> { I |-> ( ) }
|
||||
/*
|
||||
`unbind(I)` computes the environment that hides the binding of `I`.
|
||||
*/
|
||||
|
||||
|
||||
Funcon
|
||||
bound-directly(_:identifiers) : =>values
|
||||
/*
|
||||
`bound-directly(I)` returns the value to which `I` is currently bound, if any,
|
||||
and otherwise fails.
|
||||
|
||||
`bound-directly(I)` does *not* follow links. It is used only in connection with
|
||||
recursively-bound values when references are not encapsulated in abstractions.
|
||||
*/
|
||||
Rule
|
||||
lookup(Rho, I) ~> (V:values)
|
||||
--------------------------------------------------------
|
||||
environment(Rho) |- bound-directly(I:identifiers) ---> V
|
||||
Rule
|
||||
lookup(Rho, I) ~> ( )
|
||||
-----------------------------------------------------------
|
||||
environment(Rho) |- bound-directly(I:identifiers) ---> fail
|
||||
|
||||
|
||||
Funcon
|
||||
bound-value(I:identifiers) : =>values
|
||||
~> follow-if-link(bound-directly(I))
|
||||
Alias
|
||||
bound = bound-value
|
||||
/*
|
||||
`bound-value(I)` inspects the value to which `I` is currently bound, if any,
|
||||
and otherwise fails. If the value is a link, `bound-value(I)` returns the
|
||||
value obtained by following the link, if any, and otherwise fails. If the
|
||||
inspected value is not a link, `bound-value(I)` returns it.
|
||||
|
||||
`bound-value(I)` is used for references to non-recursive bindings and to
|
||||
recursively-bound values when references are encapsulated in abstractions.
|
||||
*/
|
||||
|
||||
|
||||
#### Scope
|
||||
|
||||
Funcon
|
||||
closed(X:=>T) : =>T
|
||||
/*
|
||||
`closed(X)` ensures that `X` does not depend on non-local bindings.
|
||||
*/
|
||||
Rule
|
||||
environment(map( )) |- X ---> X'
|
||||
-------------------------------------------
|
||||
environment(_) |- closed(X) ---> closed(X')
|
||||
Rule
|
||||
closed(V:T) ~> V
|
||||
|
||||
|
||||
Funcon
|
||||
scope(_:environments, _:=>T) : =>T
|
||||
/*
|
||||
`scope(D,X)` executes `D` with the current bindings, to compute an environment
|
||||
`Rho` representing local bindings. It then executes `X` to compute the result,
|
||||
with the current bindings extended by `Rho`, which may shadow or hide previous
|
||||
bindings.
|
||||
|
||||
`closed(scope(Rho, X))` ensures that `X` can reference only the bindings
|
||||
provided by `Rho`.
|
||||
*/
|
||||
Rule
|
||||
environment(map-override(Rho1, Rho0)) |- X ---> X'
|
||||
---------------------------------------------------------------------
|
||||
environment(Rho0) |- scope(Rho1:environments, X) ---> scope(Rho1, X')
|
||||
Rule
|
||||
scope(_:environments, V:T) ~> V
|
||||
|
||||
|
||||
Funcon
|
||||
accumulate(_:(=>environments)*) : =>environments
|
||||
/*
|
||||
`accumulate(D1, D2)` executes `D1` with the current bindings, to compute an
|
||||
environment `Rho1` representing some local bindings. It then executes `D2` to
|
||||
compute an environment `Rho2` representing further local bindings, with the
|
||||
current bindings extended by `Rho1`, which may shadow or hide previous
|
||||
current bindings. The result is `Rho1` extended by `Rho2`, which may shadow
|
||||
or hide the bindings of `Rho1`.
|
||||
|
||||
`accumulate(_, _)` is associative, with `map( )` as unit, and extends to any
|
||||
number of arguments.
|
||||
*/
|
||||
Rule
|
||||
D1 ---> D1'
|
||||
-------------------------------------------
|
||||
accumulate(D1, D2) ---> accumulate(D1', D2)
|
||||
Rule
|
||||
accumulate(Rho1:environments, D2) ~> scope(Rho1, map-override(D2, Rho1))
|
||||
Rule
|
||||
accumulate( ) ~> map( )
|
||||
Rule
|
||||
accumulate(D1) ~> D1
|
||||
Rule
|
||||
accumulate(D1, D2, D+) ~> accumulate(D1, accumulate(D2, D+))
|
||||
|
||||
|
||||
Funcon
|
||||
collateral(Rho*:environments*) : =>environments
|
||||
~> checked map-unite(Rho*)
|
||||
/*
|
||||
`collateral(D1, ...)` pre-evaluates its arguments with the current bindings,
|
||||
and unites the resulting maps, which fails if the domains are not pairwise
|
||||
disjoint.
|
||||
|
||||
`collateral(D1, D2)` is associative and commutative with `map( )` as unit,
|
||||
and extends to any number of arguments.
|
||||
*/
|
||||
|
||||
|
||||
#### Recurse
|
||||
|
||||
Funcon
|
||||
bind-recursively(I:identifiers, E:=>values) : =>environments
|
||||
~> recursive({I}, bind-value(I, E))
|
||||
/*
|
||||
`bind-recursively(I, E)` binds `I` to a link that refers to the value of `E`,
|
||||
representing a recursive binding of `I` to the value of `E`.
|
||||
Since `bound-value(I)` follows links, it should not be executed during the
|
||||
evaluation of `E`.
|
||||
*/
|
||||
|
||||
|
||||
Funcon
|
||||
recursive(SI:sets(identifiers), D:=>environments) : =>environments
|
||||
~> re-close(bind-to-forward-links(SI), D)
|
||||
/*
|
||||
`recursive(SI, D)` executes `D` with potential recursion on the bindings of
|
||||
the identifiers in the set `SI` (which need not be the same as the set of
|
||||
identifiers bound by `D`).
|
||||
*/
|
||||
|
||||
|
||||
Auxiliary Funcon
|
||||
re-close(M:maps(identifiers, links), D:=>environments) : =>environments
|
||||
~> accumulate(scope(M, D), sequential(set-forward-links(M), map( )))
|
||||
/*
|
||||
`re-close(M, D)` first executes `D` in the scope `M`, which maps identifiers
|
||||
to freshly allocated links. This computes an environment `Rho` where the bound
|
||||
values may contain links, or implicit references to links in abstraction
|
||||
values. It then sets the link for each identifier in the domain of `M` to
|
||||
refer to its bound value in `Rho`, and returns `Rho` as the result.
|
||||
*/
|
||||
|
||||
|
||||
Auxiliary Funcon
|
||||
bind-to-forward-links(SI:sets(identifiers)) : =>maps(identifiers, links)
|
||||
~> map-unite(interleave-map(bind-value(given, fresh-link(values)),
|
||||
set-elements(SI)))
|
||||
/*
|
||||
`bind-to-forward-links(SI)` binds each identifier in the set `SI` to a
|
||||
freshly allocated link.
|
||||
*/
|
||||
|
||||
|
||||
Auxiliary Funcon
|
||||
set-forward-links(M:maps(identifiers, links)) : =>null-type
|
||||
~> effect(interleave-map(set-link(map-lookup(M, given), bound-value(given)),
|
||||
set-elements(map-domain(M))))
|
||||
/*
|
||||
For each identifier `I` in the domain of `M`, `set-forward-links(M)` sets the
|
||||
link to which `I` is mapped by `M` to the current bound value of `I`.
|
||||
*/
|
||||
Reference in New Issue
Block a user