synthphonia/backward/
int.rs

1use std::pin::pin;
2
3use itertools::Itertools;
4use simple_rc_async::task;
5
6use crate::utils::select_ret;
7use crate::{debg, expr::Expr, galloc::AllocForAny, never};
8use crate::expr;
9
10use super::{Deducer, Problem};
11
12
13
14#[derive(Debug)]
15/// A structure using a basic deduction strategy for every type `int`, `bool`, etc. 
16pub struct IntDeducer {
17    pub nt: usize,
18    pub len: usize,
19}
20
21impl Deducer for IntDeducer {
22    /// Deduces a given `Problem` asynchronously using the `Executor`. 
23    async fn deduce(&'static self, exec: &'static crate::forward::executor::Executor, problem: Problem) -> &'static crate::expr::Expr {
24        debg!("Deducing subproblem: {} {:?}", exec.cfg[self.nt].name, problem.value);
25        let task = pin!(exec.data[self.nt].all_eq.acquire(problem.value));
26        let v = problem.value.to_int();
27        if self.len == usize::MAX || v.iter().any(|x| *x < 0) || exec.data[self.len].len().is_none() {
28            return task.await;
29        }
30        let len_task = task::spawn(async move {
31            let a = exec.data[self.len].len().unwrap();
32            let v = a.listen_for_each(v.iter().map(|a| *a as usize).collect(), |result| Some(result)).await;
33            debg!("IntDeducer: len task result: {:?}", v);
34            let result = exec.data[self.len].all_eq.get(v);
35            expr!(Len {result}).galloc()
36        });
37            
38        select_ret(task, len_task).await
39    }
40}