Function programinduction::lambda::task_by_evaluation [−][src]
pub fn task_by_evaluation<'a, E, V>(
evaluator: E,
tp: TypeSchema,
examples: &'a [(Vec<V>, V)]
) -> Task<'a, Language, Expression, &'a [(Vec<V>, V)]> where
E: Evaluator<Space = V> + Send + 'a,
V: PartialEq + Clone + Send + Sync + 'a,
Create a task based on evaluating lambda calculus expressions on test input/output pairs.
Here we let all tasks be represented by input/output pairs that are values in the space of
type V
. For example, circuits may have V
be just bool
, whereas string editing may
have V
be an enum featuring strings, chars, and natural numbers. All inputs, outputs, and
evaluated expressions must be representable by V
.
An evaluator
takes the name of a primitive and a vector of sequential inputs to the
expression (so an expression with unary type will have one input in a vec of size 1).
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::lambda::{task_by_evaluation, Language, SimpleEvaluator}; fn evaluate(name: &str, inps: &[i32]) -> Result<i32, ()> { match name { "0" => Ok(0), "1" => Ok(1), "+" => Ok(inps[0] + inps[1]), _ => unreachable!(), } } let examples = vec![(vec![2, 5], 8), (vec![1, 2], 4)]; let tp = ptp!(@arrow[tp!(int), tp!(int), tp!(int)]); let task = task_by_evaluation(SimpleEvaluator::of(evaluate), tp, &examples); let dsl = Language::uniform(vec![ ("0", ptp!(int)), ("1", ptp!(int)), ("+", ptp!(@arrow[tp!(int), tp!(int), tp!(int)])), ]); let expr = dsl.parse("(λ (+ (+ 1 $0)))").unwrap(); assert!((task.oracle)(&dsl, &expr).is_finite())