Function programinduction::pcfg::task_by_evaluation[][src]

pub fn task_by_evaluation<'a, V, E, F>(
    evaluator: &'a F,
    output: &'a V,
    tp: Type
) -> Task<'a, Grammar, AppliedRule, &'a V> where
    V: PartialEq + Clone + Sync + Debug + 'a,
    F: Fn(&str, &[V]) -> Result<V, E> + Sync + 'a, 

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 programinduction::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())