proto_vulcan/operator/
everyg.rs1use crate::engine::Engine;
13use crate::goal::{AnyGoal, InferredGoal};
14use crate::lterm::LTerm;
15use crate::operator::conj::InferredConj;
16use crate::operator::ForOperatorParam;
17use crate::solver::{Solve, Solver};
18use crate::state::State;
19use crate::stream::Stream;
20use crate::user::User;
21use std::fmt::Debug;
22use std::rc::Rc;
23
24pub struct Everyg<T, U, E, G>
25where
26 U: User,
27 E: Engine<U>,
28 G: AnyGoal<U, E>,
29 T: Debug + 'static,
30 for<'a> &'a T: IntoIterator<Item = &'a LTerm<U, E>>,
31{
32 coll: T,
33 g: Box<dyn Fn(LTerm<U, E>) -> G>,
34}
35
36impl<T, U, E, G> Debug for Everyg<T, U, E, G>
37where
38 U: User,
39 E: Engine<U>,
40 G: AnyGoal<U, E>,
41 T: Debug + 'static,
42 for<'a> &'a T: IntoIterator<Item = &'a LTerm<U, E>>,
43{
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 write!(f, "Everyg()")
46 }
47}
48
49impl<T, U, E, G> Everyg<T, U, E, G>
50where
51 U: User,
52 E: Engine<U>,
53 G: AnyGoal<U, E>,
54 T: Debug + 'static,
55 for<'a> &'a T: IntoIterator<Item = &'a LTerm<U, E>>,
56{
57 fn new(coll: T, g: Box<dyn Fn(LTerm<U, E>) -> G>) -> InferredGoal<U, E, G> {
58 InferredGoal::new(G::dynamic(Rc::new(Everyg { coll, g })))
59 }
60}
61
62impl<T, U, E, G> Solve<U, E> for Everyg<T, U, E, G>
63where
64 U: User,
65 E: Engine<U>,
66 G: AnyGoal<U, E>,
67 T: Debug + 'static,
68 for<'a> &'a T: IntoIterator<Item = &'a LTerm<U, E>>,
69{
70 fn solve(&self, solver: &Solver<U, E>, state: State<U, E>) -> Stream<U, E> {
71 let term_iter = IntoIterator::into_iter(&self.coll);
72 let goal_iter = term_iter.map(|term| (*self.g)(term.clone()));
73 InferredConj::from_iter(goal_iter).goal.solve(solver, state)
74 }
75}
76
77pub fn everyg<T, U, E, G>(param: ForOperatorParam<T, U, E, G>) -> InferredGoal<U, E, G>
78where
79 U: User,
80 E: Engine<U>,
81 G: AnyGoal<U, E>,
82 T: Debug + 'static,
83 for<'a> &'a T: IntoIterator<Item = &'a LTerm<U, E>>,
84{
85 Everyg::new(param.coll, param.g)
86}