Read Infer Predict Layer: module venture.ripl.ripl

The Read, Infer, Predict Layer.

The RIPL is the primary interface to using Venture as a Python library. One object of the Ripl class represents a distinct Venture session and offers a programmatic interface to the underlying Venture Stochastic Inference Virtual Machine (SIVM). The remainder of this document assumes a basic familiarity with the Venture language and programming model.

The methods of Ripl generally correspond to Venture instructions. Any necessary expressions can be passed in either as strings in concrete Venture syntax or as Python objects in abstract Venture syntax, or a mixture of both. Providing pre-parsed instructions is more efficient (Venture’s under-optimized parser currently imposes significant overhead), but strings in concrete syntax are likely to be more readable.

Typical usage begins by using one of the factory functions in the venture.shortcuts module:

import venture.shortcuts as s
r = s.make_ripl()
# r is a fresh Ripl
r.assume(...)
r.observe(...)
r.infer(...)
class venture.ripl.ripl.Ripl(sivm, parsers, extra_search_paths=None)

The Read, Infer, Predict Layer of one running Venture instance.

addr2Source(address)

Takes an address and gives the corresponding (unparsed) source code and expression index.

assume(name, expression, label=None, type=False)

Declare a Venture variable and initialize it by evaluating the given expression. Return its value.

The label argument, if supplied, can later be passed as an argument to report, forget, or freeze to refer to this assume directive.

The type argument, if supplied and given a true value, causes the value to be returned as a dict annotating its Venture type.

backend()

Return the name of backend powering this Ripl. Either "lite" or "puma".

bind_callback(name, callback)
bind_foreign_inference_sp(name, sp)
bind_foreign_sp(name, sp)
bind_methods_as_callbacks(obj, prefix='')

Bind every public method of the given object as a callback of the same name.

bulk_observe(exp, items, label=None)

Observe many evaluations of an expression.

Syntax: ripl.bulk_observe(“<expr>”, <iterable>)

Semantics: Operationally equivalent to:

for x in iterable:
  ripl.observe("<expr>", x)

but appreciably faster. See also open considerations and details of the semantics in observe_dataset.

clear()
continuous_inference_status()
convert_backend(name)
defaultInferProgram(program)
define(name, expression, type=False)
deregister_language(name, language)

Deregister the parser for an embedded sublanguage.

Subsequently parsed source code will not recognize that language.

directive_id_for_label(label)
disable_error_annotation()
draw_subproblem(scaffold_dict, type=False)
enable_error_annotation()
evaluate(program, type=False)
execute_instruction(instruction=None)
execute_instructions(instructions=None)
execute_parsed_program(instructions)
execute_program(program_string, type=True)
execute_program_from_file(filename)
expression_index_to_text_index(directive_id, expression_index)
force(expression, value, type=False)
forget(label_or_did, type=False)
freeze(label_or_did, type=False)
get_directive(label_or_did, type=False)
get_global_logscore()
get_mode()
get_seed()
get_text(directive_id)
humanReadable(exp=None, did=None, index=None, **kwargs)

Take a parsed expression and index and turn it into unparsed form with text indeces.

infer(params=None, type=False)
languages
list_available_modes()
list_directives(type=False, include_prelude=False, instructions=[])
load(fname)
load_io(stream)
load_plugin(name, *args, **kwargs)
load_prelude()

Load the library of Venture helper functions

loads(string)
no_error_annotation(**kwds)
observe(expression, value, label=None, type=False)
observe_dataset(proc_expression, iterable, label=None)

Observe a general dataset.

Syntax: ripl.observe_dataset(“<expr>”, <iterable>)

  • The <expr> must evaluate to a (presumably stochastic) Venture procedure. We expect in typical usage expr would just look up a recent assume.
  • The <iterable> is a Python iterable each of whose elements must be a nonempty list of valid Venture values.
  • There is no Venture syntax for this; it is accessible only when using Venture as a library.

Semantics:

  • As to its effect on the distribution over traces, this is equivalent to looping over the contents of the given iterable, calling ripl.observe on each element as ripl.observe("(<expr> *item[:-1])", item[-1]). In other words, the first elements of each item of the iterable give the arguments to the procedure given by <expr>, and the last element gives the value to observe.
  • The ripl method returns a list of directive ids, which correspond to the individual observes thus generated.

Open issues:

  • If the <expr> is itself stochastic, it is unspecified whether we notionally evaluate it once per bulk_observe or once per data item.
  • This is not the same as directly observing sufficient statistics only.
  • It is currently not possible to forget the whole bulk_observe at once.
  • Currently, list_directives will not respect the nesting structure of observations implied by bulk_observe. How can we improve this? Do we represent the bulk_observe as one directive? If so, we can hardly return a useful representation of the iterable representing the data set. If not, we will hardly win anything because list_directives will generate all those silly per-datapoint observes (every time it’s called!)
parse_program(program_string)
predict(expression, label=None, type=False)
predict_all(expression, type=False)
print_directives(*instructions, **kwargs)
print_one_directive(directive)
profile_data()
profiler_disable()
profiler_enable()
profiler_running(enable=None)
pyeval(code)
pyexec(code)
register_foreign_sp(name, sp)
register_language(name, language)

Register the parser for an embedded sublanguage.

Subsequently parsed source code will recognize substrings of the form:

@{<name> <code-in-the-language>}

and execute them according to the semantics of the registered language.

The name parameter is a string, and serves, together with the @{ token, to mark to Venture the beginning of an utterance in the registered language.

The language parameter is a constructor for a Python callable responsible for parsing the language into an appropriate embedding in Venture’s abstract syntax.

Here is the interface to sublanguage parsers in detail:

  • On encountering @{<name>, the VentureScript parser stops interpreting the input stream as VentureScript, and defers to the corresponding registered sublanguage parser. Specifically, the VentureScript parser calls the language object with no arguments to allow it to initialize.
  • Initialization must return a Python callable, subscan.
  • The VentureScript parser proceeds to call subscan repeatedly, with one input character at a time. Each call to subscan must return a 2-tuple, (done, result).
  • If done is False, the result is ignored and the VentureScript parser will call subscan again with the next character.
  • If done is True, the result must be a valid VentureScript abstract syntax tree (see below). The result will be spliced in at this point in the parse, and the VentureScript parser will resume parsing standard VentureScript. This subscan instance will not be called again, but if another invocation in the same sublanguage occurs, the language object will be invoked again to initialize a new one.

Note from this interface that the sublanguage is responsible for detecting a complete valid utterance. The characters come in one at a time because the VentureScript parser cannot predict where the utterance will end without asking the sublanguage (and, due to internal technical limitations, cannot give the sublanguage the entire input stream and continue from the unconsumed portion). It is responsibility of the sublanguage to consume the } that closes the @{ from the beginning of the invocation.

The venture.parser.venture_script.subscanner module contains an adapter that does a control inversion on the above interface. The inversion allows one to write a sublanguage with a library like Plex that expects to scan a file-like object itself, rather than exposing a callable that consumes characters. However, the sublanguage must not read the given file-like object beyond the end of the utterance, as there is no way to put unused characters back.

There are no restrictions on the parse tree that a subparser may emit. In principle, this permits very deep integration of arbitrary syntaxes, provided their underlying implementation can be expressed as calls to appropriate Venture macros or stochastic procedures. It is also possible to fall back to very shallow integration—just consume a valid utterance and emit a syntax tree consisting of applying the target interpreter (packaged as a stochastic procedure) to a quoted string.

The VentureScript abstract syntax tree API comes in two parts.

  • Bare abstract syntax trees may are constructed by methods of the venture.value.dicts module.
  • A parser is expected to emit a syntax tree annotated with source code locations, using the Located class in the venture.parser.ast module.

Embedded sublanguage syntaxes are only available in the VentureScript surface syntax, not the abstract surface syntax. The latter parses to abstract syntax trees more directly, so just calling the implementation SP(s) of the desired sublanguage is more natural in that context.

reinit_inference_problem(num_particles=None)
report(label_or_did, type=False)
sample(expression, type=False)
sample_all(expression, type=False)
save(fname, extra=None)
save_io(stream, extra=None)
saves(extra=None)
set_mode(mode)
set_seed(seed)
start_continuous_inference(program=None)
stop_continuous_inference(type=False)
venture.ripl.ripl.load_library(name, search_paths)