# 10 First-class Computation Spaces: `Space`

First-class computation spaces can be used to program inference engines for problem solving.

`is`

  > `{Space.is` `+X``` `?B``}`

  tests whether `X` is a space.

`new`

  > `{Space.new` `+P``` `?Space``}`

  returns a newly created space, in which a thread containing an application of the unary procedure `P` to the root variable of `Space` is created.

`ask`

  > `{Space.ask` `+Space``` `?T``}`

  waits until `Space` becomes stable or merged and then returns the status of `Space`.

  If `Space` is merged, the atom `merged` is returned.

  If `Space` is stable and:

  failed

    the atom `failed` is returned.

  succeeded

    and there are no threads in `Space` synchronizing on choices, the atom `succeeded` is returned.

  succeeded

    and there is at least one thread in `Space` which synchronizes on a choice the tuple `alternatives(`I`)` is returned, where I gives the number of alternatives of the selected choice.

  Synchronizes on stability of `Space`.

  Raises a runtime error if the current space is not admissible for `Space`.

`askVerbose`

  > `{Space.askVerbose` `+Space``` `?T``}`

  returns the status of `Space` in verbose form. Reduces immediately, even if `Space` is not yet stable.

  If `Space` becomes merged, the atom `merged` is returned.

  If `Space` becomes suspended (that is, blocked but not stable), `T` is bound to the tuple `suspended(`T1`)`. T1 is a future that is bound to the status of `Space` when `Space` becomes unblocked again.

  If `Space` is stable and:

  failed

    the atom `failed` is returned.

  succeeded

    and there are no threads in `Space` synchronizing on choices, the tuple `succeeded(`A`)` is returned. The atom A is either `stuck`, when `Space` still contains threads, or `entailed` otherwise.

  succeeded

    and there is at least one thread in `Space` which synchronizes on a choice the tuple `alternatives(`I`)` is returned, where `I` gives the number of alternatives of the selected choice.

  Does not synchronize on stability of `Space`.

  Raises a runtime error if the current space is not admissible for `Space`.

`merge`

  > `{Space.merge` `+Space``` `X``}`

  merges `Space` with the current space and constrains `X` to the root variable of `Space`.

  Does not synchronize on stability of `Space`.

  Raises a runtime error if `Space` is already merged, or if the current space is not admissible for `Space`.

`clone`

  > `{Space.clone` `+Space1``` `?Space2``}`

  blocks until `Space1` becomes stable and returns a new space which is a copy of `Space1`.

  Synchronizes on stability of `Space`.

  Raises a runtime error if `Space` is already merged, or if the current space is not admissible for `Space`.

`inject`

  > `{Space.inject` `+Space``` `+P``}`

  creates a thread in the space `Space` which contains an application of the unary procedure `P` to the root variable of `Space`.

  Does not synchronize on stability of `Space`.

  Raises a runtime error if `Space` is already merged, or if the current space is not admissible for `Space`.

`kill`

  > `{Space.kill` `+Space``}`

  kills a space by injecting failure into `Space`.

  Can be defined by

  > `proc {Space.kill S}
  > {Space.inject S proc {$ _} fail end}
  > end`

  Does not synchronize on stability of `Space`.

  Raises a runtime error if `Space` is already merged, or if the current space is not admissible for `Space`.

`commit`

  > `{Space.commit` `+Space``` `+IT``}`

  blocks until `Space` becomes stable and then commits to alternatives of the selected choice of `Space`.

  If `IT` is a pair of integers l`#`r then all but the l, l + 1, ..., r alternatives of the selected choice of `Space` are discarded. If a single alternative remains, the topmost choice is replaced by this alternative. If no alternative remains, the space is failed.

  An integer value for `IT` is an abbrevation for the pair `IT``#``IT`.

  Synchronizes on stability of `Space`.

  Raises a runtime error, if `Space` has been merged already, if there exists no selected choice in `Space`, or if the current space is not admissible for `Space`.

`waitStable`

  > `{Space.waitStable}`

  blocks until the current space (the space that hosts the current thread) becomes stable. `Space.waitStable` is used mainly for programming distribution strategies (see for example Chapter 9 of ``Finite Domain Constraint Programming in Oz. A Tutorial.''), where for accurate variable selection it is required that all propagation has been carried out.

  If executed in the toplevel space, it will block forever.

`choose`

  > `{Space.choose` `+I1``` `?I2``}`

  blocks until the current space becomes stable. When the current space becomes stable it creates a choice point with `I1` alternatives. `I2` is bound to the value selected by `Space.commit`. Reduces as soon as `I2` becomes bound.

  `Space.choose` is a primitive intended for programming abstractions. For example, the Mozart-compiler expands the following `choice`-statement

  > `choice` `S1``[]` `S2` `end`

  to the following statement

  > `case {Space.choose 2}
  > of 1 then` `S1``
  > [] 2 then` `S2``
  > end`

  If executed in the toplevel space, it will block forever.