canrun/goals/ops/
div.rs

1use crate::{
2    goals::{map_2, Goal},
3    Unify, Value,
4};
5use std::ops::{Div, Mul};
6
7/** Divide one value with another.
8
9# Example:
10```
11use canrun::{LVar, Query};
12use canrun::ops::div;
13
14let x = LVar::new();
15let goal = div(3, 2, x);
16let results: Vec<_> = goal.query(x).collect();
17assert_eq!(results, vec![1]);
18```
19*/
20pub fn div<T, A, B, C>(a: A, b: B, c: C) -> impl Goal
21where
22    T: Unify + Mul<Output = T> + Div<Output = T> + Copy,
23    A: Into<Value<T>>,
24    B: Into<Value<T>>,
25    C: Into<Value<T>>,
26{
27    map_2(a, b, c, |a, b| *a / *b, |a, c| *a / *c, |b, c| *b * *c)
28}
29
30#[cfg(test)]
31mod tests {
32    use super::div;
33    use crate::{goal_vec, goals::unify, LVar};
34
35    #[test]
36    fn succeeds() {
37        let (x, y, z) = (LVar::new(), LVar::new(), LVar::new());
38        let goals = goal_vec![unify(x, 6), unify(y, 3), unify(z, 2), div(x, y, z)];
39        goals.assert_permutations_resolve_to(&(x, y, z), vec![(6, 3, 2)]);
40    }
41
42    #[test]
43    fn fails() {
44        let (x, y, z) = (LVar::new(), LVar::new(), LVar::new());
45        let goals = goal_vec![unify(x, 6), unify(y, 3), unify(z, 5), div(x, y, z)];
46        goals.assert_permutations_resolve_to(&(x, y, z), vec![]);
47    }
48}