proto_vulcan/operator/
anyo.rs1use crate::engine::Engine;
2use crate::goal::{AnyGoal, Goal};
3use crate::operator::conde::conde;
4use crate::operator::conj::Conj;
5use crate::operator::OperatorParam;
6use crate::solver::{Solve, Solver};
7use crate::state::State;
8use crate::stream::Stream;
9use crate::user::User;
10use crate::GoalCast;
11use std::rc::Rc;
12
13#[derive(Derivative)]
14#[derivative(Debug(bound = "U: User"))]
15pub struct Anyo<U, E>
16where
17 U: User,
18 E: Engine<U>,
19{
20 g: Goal<U, E>,
21}
22
23impl<U, E> Anyo<U, E>
24where
25 U: User,
26 E: Engine<U>,
27{
28 pub fn new(g: Goal<U, E>) -> Goal<U, E> {
29 Goal::dynamic(Rc::new(Anyo { g }))
30 }
31}
32
33impl<U, E> Solve<U, E> for Anyo<U, E>
34where
35 U: User,
36 E: Engine<U>,
37{
38 fn solve(&self, solver: &Solver<U, E>, state: State<U, E>) -> Stream<U, E> {
39 let g = self.g.clone();
40 let g2 = self.g.clone();
41 let goal = proto_vulcan!(
42 conde {
43 g,
44 anyo {
45 g2
46 },
47 }
48 );
49 goal.solve(solver, state)
50 }
51}
52
53pub fn anyo<U, E>(param: OperatorParam<U, E, Goal<U, E>>) -> Goal<U, E>
81where
82 U: User,
83 E: Engine<U>,
84{
85 Anyo::new(GoalCast::cast_into(Conj::from_conjunctions(param.body)))
86}
87
88#[cfg(test)]
89mod tests {
90 use super::anyo;
91 use crate::operator::conde::conde;
92 use crate::prelude::*;
93
94 #[test]
95 fn test_anyo_1() {
96 let query = proto_vulcan_query!(|q| {
97 conde {
98 anyo {
99 false == q,
100 },
101 true == q,
102 }
103 });
104 let mut iter = query.run();
105 assert_eq!(iter.next().unwrap().q, true);
106 assert_eq!(iter.next().unwrap().q, false);
107 assert_eq!(iter.next().unwrap().q, false);
108 assert_eq!(iter.next().unwrap().q, false);
109 assert_eq!(iter.next().unwrap().q, false);
110 }
111
112 #[test]
113 fn test_anyo_2() {
114 let query = proto_vulcan_query!(|q| {
115 anyo {
116 conde {
117 1 == q,
118 2 == q,
119 3 == q,
120 }
121 }
122 });
123 let mut iter = query.run();
124 assert_eq!(iter.next().unwrap().q, 1);
125 assert_eq!(iter.next().unwrap().q, 2);
126 assert_eq!(iter.next().unwrap().q, 3);
127 assert_eq!(iter.next().unwrap().q, 1);
128 assert_eq!(iter.next().unwrap().q, 2);
129 assert_eq!(iter.next().unwrap().q, 3);
130 }
131
132 #[test]
133 fn test_anyo_3() {
134 let query = proto_vulcan_query!(|q| {
136 loop {
137 conde {
138 1 == q,
139 2 == q,
140 3 == q,
141 }
142 }
143 });
144 let mut iter = query.run();
145 assert_eq!(iter.next().unwrap().q, 1);
146 assert_eq!(iter.next().unwrap().q, 2);
147 assert_eq!(iter.next().unwrap().q, 3);
148 assert_eq!(iter.next().unwrap().q, 1);
149 assert_eq!(iter.next().unwrap().q, 2);
150 assert_eq!(iter.next().unwrap().q, 3);
151 }
152}