synthphonia/expr/
context.rs

1
2use derive_more::{DebugCustom, Constructor};
3use itertools::Itertools;
4use crate::{parser::{ioexamples::IOExamples, problem::PBEProblem}, tree_learning::Bits, value::Value};
5
6use super::Expr;
7
8#[derive(DebugCustom, Constructor, Clone)]
9#[debug(fmt = "(n: {:?}, p: {:?})", n, p)]
10/// A struct that encapsulates the contextual information used during a string synthesis evaluation. 
11pub struct Context{
12    pub len: usize, 
13    /// Store inputs
14    pub p: Vec<Value>,
15    /// No longer used
16    pub n: Vec<Value>,
17    pub output: Value,
18}
19
20impl Context {
21    /// Returns the length of the context of the values.
22    pub fn len(&self) -> usize { self.len }
23    
24    /// Retrieve a input value from the context based on the provided index.
25    pub fn get(&self, index: i64) -> Option<&Value> {
26        if index >= 0 { self.p.get(index as usize) }
27        else { self.n.get((!index) as usize) }
28    }
29    /// Provides an iterator over the inputs
30    pub fn iter(&self) -> impl Iterator<Item=Value> + '_ {
31        [self.output].into_iter().chain(self.p.iter().cloned()).chain(self.n.iter().cloned())
32    }
33    /// Provides an iterator over all input values contained within a given context. 
34    pub fn inputs(&self) -> impl Iterator<Item=Value> + '_ {
35        self.p.iter().cloned().chain(self.n.iter().cloned())
36    }
37    /// Returns an iterator over the output values within the context. 
38    pub fn outputs(&self) -> impl Iterator<Item=Value> + '_ {
39        [self.output].into_iter()
40    }
41    /// Evaluates an expression within the given context and determines its equivalence to the context's output. 
42    pub fn evaluate(&self, e: &'static Expr) -> Option<Bits> {
43        let v = e.eval(self);
44        self.output.eq_bits(&v)
45    }
46    /// Creates a new instance by filtering the existing values with provided indices. 
47    pub fn with_examples(&self, exs: &[usize]) -> Context {
48        Context {
49            len: exs.len(),
50            p: self.p.iter().map(|x| x.with_examples(exs)).collect_vec(),
51            n: self.n.iter().map(|x| x.with_examples(exs)).collect_vec(),
52            output: self.output.with_examples(exs),
53        }
54    }
55}
56
57impl std::ops::Index<i64> for Context {
58    type Output = Value;
59
60    /// Provides a method for retrieving elements from a context using an index. 
61    fn index(&self, index: i64) -> &Self::Output {
62        self.get(index).expect("out of range")
63    }
64}
65
66
67impl Context {
68    /// Creates a `Context` instance from a reference to `IOExamples`. 
69    pub fn from_examples(examples: &IOExamples) -> Self {
70        Self {
71            len: examples.output.len(),
72            p: examples.inputs.clone(),
73            n: Vec::new(),
74            output: examples.output
75        }
76    }
77}
78