Packages

class MLValue[A] extends FutureValue

A type safe wrapper for values stored in the Isabelle process managed by Isabelle.

As explained in the documentation of Isabelle, the Isabelle process has an object store of values, and the class Isabelle.ID is a reference to an object in that object store. However, values of different types share the same object store. Thus Isabelle.ID is not type safe: there are compile time guarantees that the value referenced by that ID has a specific type.

MLValue[A] is a thin wrapper around an ID id (more precisely, a future holding an ID). It is guaranteed that id references a value in the Isabelle process of an ML type corresponding to A (or throw an exception). (It is possible to violate this guarantee by type-casting the MLValue though.) For supported types A, it is possible to automatically translate a Scala value x of type A into an MLValue[A] (which behind the scenes means that x is transferred to the Isabelle process and added to the object store) and also to automatically translate an MLValue[A] back to a Scala value of type A. Supported types are Int, Long, Boolean, Unit, String, and lists and tuples (max. 7 elements) of supported types. (It is also possible for A to be the type MLValue[...], see MLValueConverter for explanations (TODO add these explanations).) It is possible to add support for other types, see MLValue.Converter for instructions (TODO add these instructions). Using this mechanism, support for the terms, types, theories, contexts, and theorems has been added in package de.unruh.isabelle.pure.

In more detail:

  • For any supported Scala type A there should be a unique corresponding ML type a. (This is not enforced if we add support for new types, but if we violate this, we loose type safety.)
  • Several Scala types A are allowed to correspond to the same ML type a. (E.g., both Long and Int correspond to the unbounded int in ML.)
  • For each supported type A, the following must be specified (via an implicit MLValue.Converter):
    • an encoding of a as an exception (to be able to store it in the object store)
    • ML functions to translate between a and exceptions and back
    • retrieve function: how to retrieve an exception encoding an ML value of type a and translate it into an A in Scala
    • store function: how to translate an A in Scala into an an exception encoding an ML value of type a and store it in the object store.
  • MLValue(x) automatically translates x:A into a value of type a (using the retrieve function) and returns an MLValue[A].
  • If m : MLValue[A], then m.retrieve (asynchronous) and m.retrieveNow (synchronous) decode the ML value in the object store and return a Scala value of type A.
  • ML code that operates on values in the Isabelle process can be specified using MLValue.compileValue and MLValue.compileFunction[D,R]*. This ML code directly operates on the corresponding ML type a and does not need to consider the encoding of ML values as exceptions or how ML types are serialized to be transferred to Scala (all this is handled automatically behind the scenes using the information provided by the implicit MLValue.Converter).
  • To be able to use the automatic conversions etc., converters need to be imported for supported types. The converters provided by this package can be imported by import de.unruh.isabelle.mlvalue.Implicits._.

Note: Some operations take an Isabelle instance as an implicit argument. It is required that this instance the same as the one relative to which the MLValue was created.

A full example:

implicit val isabelle: Isabelle = new Isabelle(...)
import scala.concurrent.ExecutionContext.Implicits._

// Create an MLValue containing an integer
val intML : MLValue[Int] = MLValue(123)
// 123 is now stored in the object store

// Fetching the integer back
val int : Int = intML.retrieveNow
assert(int == 123)

// The type parameter of MLValue ensures that the following does not compile:
// val string : String = intML.retrieveNow

// We write an ML function that squares an integer and converts it into a string
val mlFunction : MLFunction[Int, String] =
  MLValue.compileFunction[Int, String]("fn i => string_of_int (i*i)")

// We can apply the function to an integer stored in the Isabelle process
val result : MLValue[String] = mlFunction(intML)
// The result is still stored in the Isabelle process, but we can retrieve it:
val resultHere : String = result.retrieveNow
assert(resultHere == "15129")

Not that the type annotations in this example are all optional, the compiler infers them automatically. We have included them for clarity only.

A

the Scala type corresponding to the ML type of the value referenced by id

Linear Supertypes
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. MLValue
  2. FutureValue
  3. AnyRef
  4. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Instance Constructors

  1. new MLValue(id: Future[ID])

    id

    the ID of the referenced object in the Isabelle process

    Attributes
    protected

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def await: Unit
    Definition Classes
    MLValueFutureValue
  6. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @native() @HotSpotIntrinsicCandidate()
  7. def debugInfo(implicit isabelle: Isabelle, ec: ExecutionContext): String

    Returns a textual representation of the value in the ML process as it is stored in the object store (i.e., encoded as an exception).

    Returns a textual representation of the value in the ML process as it is stored in the object store (i.e., encoded as an exception). E.g., an integer 3 would be represented as "E_Int 3".

  8. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  9. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  10. def force: MLValue.this.type

    Waits till the computation of this value (in the Isabelle process) has finished.

    Waits till the computation of this value (in the Isabelle process) has finished. (Or until an exception is thrown.)

    returns

    this value, but it is guaranteed to have completed the computation

    Definition Classes
    FutureValue
  11. def forceFuture(implicit ec: ExecutionContext): Future[MLValue.this.type]

    A future containing this value with the computation completed.

    A future containing this value with the computation completed. In particular, if this value throws an exception upon computation, the future holds that exception.

    Roughly the same as Future { this.force }.

    Definition Classes
    FutureValue
  12. def function[D, R](implicit ev: =:=[MLValue[A], MLValue[(D) => R]]): MLFunction[D, R]

    Returns this MLValue as an MLFunction, assuming this MLValue has a type of the form MLValue[D => R].

    Returns this MLValue as an MLFunction, assuming this MLValue has a type of the form MLValue[D => R]. If this MLValue is MLValue[D => R], it means it references a function value in the ML process. Converting it to an MLFunction <: MLValue gives us access to additional methods for applying this function.

    See also

    MLFunction

  13. def function2[D1, D2, R](implicit ev: =:=[MLValue[A], MLValue[((D1, D2)) => R]]): MLFunction2[D1, D2, R]

    Analogous to function but for functions that take a pair as argument, i.e., this : MLValue[((D1, D2)) => R].

    Analogous to function but for functions that take a pair as argument, i.e., this : MLValue[((D1, D2)) => R].

    See also

    MLFunction2

  14. def function3[D1, D2, D3, R](implicit ev: =:=[MLValue[A], MLValue[((D1, D2, D3)) => R]]): MLFunction3[D1, D2, D3, R]

    Analogous to function but for functions that take a 3-tuple as argument, i.e., this : MLValue[((D1, D2, D3)) => R].

    Analogous to function but for functions that take a 3-tuple as argument, i.e., this : MLValue[((D1, D2, D3)) => R].

    See also

    MLFunction3

  15. def function4[D1, D2, D3, D4, R](implicit ev: =:=[MLValue[A], MLValue[((D1, D2, D3, D4)) => R]]): MLFunction4[D1, D2, D3, D4, R]

    Analogous to function but for functions that take a 4-tuple as argument, i.e., this : MLValue[((D1, D2, D3, D4)) => R].

    Analogous to function but for functions that take a 4-tuple as argument, i.e., this : MLValue[((D1, D2, D3, D4)) => R].

    See also

    MLFunction4

  16. def function5[D1, D2, D3, D4, D5, R](implicit ev: =:=[MLValue[A], MLValue[((D1, D2, D3, D4, D5)) => R]]): MLFunction5[D1, D2, D3, D4, D5, R]

    Analogous to function but for functions that take a 5-tuple as argument, i.e., this : MLValue[((D1, D2, D3, D4, D5)) => R].

    Analogous to function but for functions that take a 5-tuple as argument, i.e., this : MLValue[((D1, D2, D3, D4, D5)) => R].

    See also

    MLFunction5

  17. def function6[D1, D2, D3, D4, D5, D6, R](implicit ev: =:=[MLValue[A], MLValue[((D1, D2, D3, D4, D5, D6)) => R]]): MLFunction6[D1, D2, D3, D4, D5, D6, R]

    Analogous to function but for functions that take a 6-tuple as argument, i.e., this : MLValue[((D1, D2, D3, D4, D5, D6)) => R].

    Analogous to function but for functions that take a 6-tuple as argument, i.e., this : MLValue[((D1, D2, D3, D4, D5, D6)) => R].

    See also

    MLFunction6

  18. def function7[D1, D2, D3, D4, D5, D6, D7, R](implicit ev: =:=[MLValue[A], MLValue[((D1, D2, D3, D4, D5, D6, D7)) => R]]): MLFunction7[D1, D2, D3, D4, D5, D6, D7, R]

    Analogous to function but for functions that take a 7-tuple as argument, i.e., this : MLValue[((D1, D2, D3, D4, D5, D6, D7)) => R].

    Analogous to function but for functions that take a 7-tuple as argument, i.e., this : MLValue[((D1, D2, D3, D4, D5, D6, D7)) => R].

    See also

    MLFunction7

  19. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @native() @HotSpotIntrinsicCandidate()
  20. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native() @HotSpotIntrinsicCandidate()
  21. val id: Future[ID]
  22. def insertMLValue[C[_], B](implicit ev: =:=[A, C[B]]): MLValue[C[MLValue[B]]]

    Specialized type cast that inserts MLValue[] in arbitrary positions in the type parameter of this MLValue.

    Specialized type cast that inserts MLValue[] in arbitrary positions in the type parameter of this MLValue. E.g., we can type cast this : MLValue[List[X]] to MLValue[List[MLValue[X]]] by invoking this.insertMLValue[List,X] Such type casts are safe because the the way MLValue[...] is interpreted in the type parameter to MLValue (see MLValueConverter (TODO: document that one)). The same type cast could be achieved using .asInstanceOf, but insertMLValue guarantees that no unsafe cast is accidentally performed.

    Annotations
    @inline()
  23. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  24. def logError(message: => String)(implicit executionContext: ExecutionContext): MLValue.this.type
  25. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  26. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @HotSpotIntrinsicCandidate()
  27. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @HotSpotIntrinsicCandidate()
  28. def removeMLValue[C[_], B](implicit ev: =:=[A, C[MLValue[B]]]): MLValue[C[B]]

    Specialized type cast that removes MLValue[] in arbitrary positions in the type parameter of this MLValue.

    Specialized type cast that removes MLValue[] in arbitrary positions in the type parameter of this MLValue. E.g., we can type cast this : MLValue[List[MLValue[X]]] to MLValue[List[X]] by invoking this.removeMLValue[List,X] Such type casts are safe because the the way MLValue[...] is interpreted in the type parameter to MLValue (see MLValueConverter (TODO: document that one)). The same type cast could be achieved using .asInstanceOf, but insertMLValue guarantees that no unsafe cast is accidentally performed.

    Annotations
    @inline()
  29. def retrieve(implicit converter: Converter[A], isabelle: Isabelle, ec: ExecutionContext): Future[A]

    Retrieves the value referenced by this MLValue from the Isabelle process.

    Retrieves the value referenced by this MLValue from the Isabelle process.

    In particular, the value in the Isabelle process (a value in ML) is translated to a Scala value.

    converter

    This converter specifies how the value is to be retrieved from the Isabelle process and translated into a Scala value of type A

    isabelle

    The Isabelle instance holding the value. This must be the same Isabelle instance relative to which the MLValue was created. (Otherwise unspecified data is returned or an exception thrown.) In an application with only a single Isabelle instance that instance can safely be declared as an implicit.

    returns

    Future holding the value (as a Scala value) or an IsabelleException if the computation of that value or the transfer to Scala failed.

    Annotations
    @inline()
  30. def retrieveNow(implicit converter: Converter[A], isabelle: Isabelle, ec: ExecutionContext): A

    Like retrieve but returns the Scala value directly instread of a future (blocks till the computation and transfer finish.

    Like retrieve but returns the Scala value directly instread of a future (blocks till the computation and transfer finish.

    Annotations
    @inline()
  31. def someFuture: Future[Any]
    Definition Classes
    MLValueFutureValue
  32. def stateString: String

    A utility method that returns "" if this value was successfully computed, " (computing)" if it still computes, and " (failed)" if it finished with an exception.

    A utility method that returns "" if this value was successfully computed, " (computing)" if it still computes, and " (failed)" if it finished with an exception.

    This can be useful to constructing human readable messages about this value.

    Definition Classes
    FutureValue
  33. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  34. def toString(): String
    Definition Classes
    AnyRef → Any
  35. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  36. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()
  37. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])

Deprecated Value Members

  1. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable]) @Deprecated
    Deprecated

Inherited from FutureValue

Inherited from AnyRef

Inherited from Any

Ungrouped