pub struct Program {
pub fugue_program: u32,
pub body: Vec<Stmt>,
pub ret: Expr,
}Expand description
A program: statements and a return expression, plus the format version.
A Program is plain data. Build one with Program::parse (the text
syntax), Program::from_json, or directly from the AST types; then
compile it against a Registry
and Data to get a CompiledProgram
that builds real Models.
Display prints the canonical text form, which Program::parse reads
back to an equal program.
use fugue::program::Program;
let text = Program::parse(
r#"let p <- sample(addr!("p"), Beta(2.0, 2.0));
observe(addr!("y"), Bernoulli(p), true);
pure(p)"#,
)
.unwrap();
let json = Program::from_json(&text.to_json().unwrap()).unwrap();
assert_eq!(text, json);
assert_eq!(Program::parse(&text.to_string()).unwrap(), text);Fields§
§fugue_program: u32Format version; FORMAT_VERSION for programs this build writes.
body: Vec<Stmt>The statements, in order.
ret: ExprThe expression pure(..) returns.
Implementations§
Source§impl Program
impl Program
Sourcepub fn from_json(json: &str) -> Result<Program, ProgramError>
pub fn from_json(json: &str) -> Result<Program, ProgramError>
Read a program from its JSON form.
The fugue_program version is checked before the rest of the
document is decoded, so a program written by a newer format fails with
ProgramError::UnsupportedVersion rather than with whatever node its
newer syntax trips over first. Unknown fields are rejected, so a
misspelt key is an error, not a silently different program.
use fugue::program::{Program, ProgramError};
let p = Program::from_json(
r#"{"fugue_program": 1, "body": [], "ret": {"op": "f64", "value": 1.5}}"#,
)
.unwrap();
assert_eq!(p, Program::parse("pure(1.5)").unwrap());
let newer = r#"{"fugue_program": 2, "body": [], "ret": {"op": "f64", "value": 1.5}}"#;
assert!(matches!(
Program::from_json(newer),
Err(ProgramError::UnsupportedVersion { found: 2, supported: 1 })
));Sourcepub fn to_json(&self) -> Result<String, ProgramError>
pub fn to_json(&self) -> Result<String, ProgramError>
The program’s JSON form (compact). Fails for a program that would not
read back: a non-current version, a non-finite literal, a name that is
not an identifier, or nesting beyond MAX_NESTING.
Sourcepub fn to_json_pretty(&self) -> Result<String, ProgramError>
pub fn to_json_pretty(&self) -> Result<String, ProgramError>
The program’s JSON form, pretty-printed. Same checks as
to_json.
Source§impl Program
impl Program
Sourcepub fn parse(src: &str) -> Result<Program, ProgramError>
pub fn parse(src: &str) -> Result<Program, ProgramError>
Parse the text syntax (the grammar is in the module docs).
Parsing needs no registry: names are resolved by
compile, so an unknown distribution is a compile
error, not a syntax error.
use fugue::program::{Program, ProgramError};
let p = Program::parse(
r#"let mu <- sample(addr!("mu"), Normal::new(0.0, 1.0).unwrap());
observe(addr!("y"), Normal(mu, 1.0), 0.5);
pure(mu)"#,
)
.unwrap();
assert_eq!(p.body.len(), 2);
match Program::parse("let x = 1.0;\nlet y = ;\npure(x)") {
Err(ProgramError::Syntax { line, .. }) => assert_eq!(line, 2),
other => panic!("{other:?}"),
}Sourcepub fn compile(
&self,
registry: &Registry,
data: &Data,
) -> Result<CompiledProgram, ProgramError>
pub fn compile( &self, registry: &Registry, data: &Data, ) -> Result<CompiledProgram, ProgramError>
Check the program against a registry and data, resolving every name, and prepare it for building models.
Everything that can be known before running is checked here: unknown
variables (including assignment to one), unknown distributions and
functions, argument counts, break outside a loop, and the structural
checks of to_json. The data’s names are bound as
variables in an outer scope (a program’s own let may shadow them).
use fugue::program::{Data, Program, Registry};
let program = Program::parse("pure(y.len())").unwrap();
let registry = Registry::new();
assert!(program.compile(®istry, &Data::new()).is_err()); // unknown `y`
let compiled = program
.compile(®istry, &Data::new().with("y", vec![1.0, 2.0]))
.unwrap();Trait Implementations§
Source§impl<'de> Deserialize<'de> for Program
impl<'de> Deserialize<'de> for Program
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Display for Program
The canonical text form; Program::parse reads it back to an equal
program (for any program to_json accepts).
impl Display for Program
The canonical text form; Program::parse reads it back to an equal
program (for any program to_json accepts).
Source§impl FromStr for Program
impl FromStr for Program
Source§fn from_str(s: &str) -> Result<Program, ProgramError>
fn from_str(s: &str) -> Result<Program, ProgramError>
Same as Program::parse.