Function programinduction::lambda::task_by_evaluation
source · pub fn task_by_evaluation<E, V>(
evaluator: E,
tp: TypeScheme,
examples: impl AsRef<[(Vec<V>, V)]> + Sync
) -> impl Task<[(Vec<V>, V)], Representation = Language, Expression = Expression>
Expand description
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 polytype::{ptp, tp};
use programinduction::{Task, 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::from(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())