Function programinduction::pcfg::task_by_evaluation
source · pub fn task_by_evaluation<'a, V, E, F>(
evaluator: &'a F,
output: &'a V,
tp: Type
) -> impl Task<V, Representation = Grammar, Expression = AppliedRule> + 'a
Expand description
Create a task based on evaluating a PCFG sentence and comparing its output against data.
Here we let all tasks be represented by an output valued in the space of type V
. In practice,
V
will often be an enum corresponding to each nonterminal in the PCFG. All outputs and
evaluated sentences must be representable by V
.
An evaluator
takes the name of a production and a vector corresponding to evaluated results
of each child node of the production in a particular derivation.
The resulting task is “all-or-nothing”: the oracle returns either 0
if all examples are
correctly hit or f64::NEG_INFINITY
otherwise.
Examples
use polytype::tp;
use programinduction::{Task, pcfg::{task_by_evaluation, Grammar, Rule}};
fn evaluator(name: &str, inps: &[i32]) -> Result<i32, ()> {
match name {
"0" => Ok(0),
"1" => Ok(1),
"plus" => Ok(inps[0] + inps[1]),
_ => unreachable!(),
}
}
let g = Grammar::new(
tp!(EXPR),
vec![
Rule::new("0", tp!(EXPR), 1.0),
Rule::new("1", tp!(EXPR), 1.0),
Rule::new("plus", tp!(@arrow[tp!(EXPR), tp!(EXPR), tp!(EXPR)]), 1.0),
],
);
let output = 4;
let tp = tp!(EXPR);
let task = task_by_evaluation(&evaluator, &output, tp);
let expr = g.parse("plus(1, plus(1, plus(1,1)))").unwrap();
assert!(task.oracle(&g, &expr).is_finite())