path_semantics_std/
path.rs

1use *;
2
3pub trait Path<T> {
4    type Lift;
5
6    fn path_force(&self, arg: T) -> <Self as Path<T>>::Lift;
7
8    /// Can call method if the existential paths of constrained input matches.
9    fn path(&self, arg: T) -> <Self as Path<T>>::Lift
10        where <Self as Path<T>>::Lift: ExPath<
11                    Lift = <<T as Constrain<<Self as ExPath>::Lift>>::Lift as ExPath>::Lift>,
12              T: Constrain<<Self as ExPath>::Lift>,
13              <T as Constrain<<Self as ExPath>::Lift>>::Lift: ExPath,
14              Self: ExPath
15    {
16        self.path_force(arg)
17    }
18}
19
20macro_rules! path_impl {
21    (sym $a:ident , $b:ident , $c:ident) => {
22        impl<T: Clone> Path<$b> for $a<T>
23            where $b<T>: ExPath
24        {
25            type Lift = $c<<<$b as Constrain<T>>::Lift as ExPath>::Lift>;
26
27            fn path_force(&self, arg: $b) -> Self::Lift {
28                $c {i: arg.i_force(self.i.clone()).ex_path()}
29            }
30        }
31    };
32    (sym $a:ident , $b:ident , $c:ident < $t:ident >) => {
33        impl<T: Clone> Path<$b> for $a<T>
34            where $b<T>: ExPath
35        {
36            type Lift = $c<$t, <<$b as Constrain<T>>::Lift as ExPath>::Lift>;
37
38            fn path_force(&self, arg: $b) -> Self::Lift {
39                $c {t: PhantomData, i: arg.i_force(self.i.clone()).ex_path()}
40            }
41        }
42    };
43    (sym $a:ident < $t:ident >, $b:ident , $c:ident) => {
44        impl<T: Clone> Path<$b> for $a<$t, T>
45            where $b<T>: ExPath
46        {
47            type Lift = $c<<<$b as Constrain<T>>::Lift as ExPath>::Lift>;
48
49            fn path_force(&self, arg: $b) -> Self::Lift {
50                $c {i: arg.i_force(self.i.clone()).ex_path()}
51            }
52        }
53    };
54    (sym $a:ident < $t:ident >, $b:ident < $bt:ident >, $c:ident) => {
55        impl<T: Clone> Path<$b<$bt>> for $a<$t, T>
56            where $b<$bt, T>: ExPath
57        {
58            type Lift = $c<<<$b<$bt> as Constrain<T>>::Lift as ExPath>::Lift>;
59
60            fn path_force(&self, arg: $b<$bt>) -> Self::Lift {
61                $c {i: arg.i_force(self.i.clone()).ex_path()}
62            }
63        }
64    };
65    (sym $a:ident < $t:ident >, $b:ident < $bt:ident >, $c:ident < $t2:ident >) => {
66        impl<T: Clone> Path<$b<$bt>> for $a<$t, T>
67            where $b<$bt, T>: ExPath
68        {
69            type Lift = $c<$t2, <<$b<$bt> as Constrain<T>>::Lift as ExPath>::Lift>;
70
71            fn path_force(&self, arg: $b<$bt>) -> Self::Lift {
72                $c {t: PhantomData, i: arg.i_force(self.i.clone()).ex_path()}
73            }
74        }
75    };
76    ($a:ident , $b:ident , $c:ident) => {
77        impl Path<$b> for $a {
78            type Lift = $c;
79
80            fn path_force(&self, _: $b) -> Self::Lift {
81                $c::default()
82            }
83        }
84    }
85}
86
87path_impl!{sym Or, Not, And}
88path_impl!{sym And, Not, Or}
89path_impl!{sym Eq<bool>, Not, Xor}
90path_impl!{sym Xor, Not, Eq<bool>}
91path_impl!{sym Nor, Not, Nand}
92path_impl!{sym Nand, Not, Nor}
93path_impl!{sym Exc, Not, Nrexc}
94path_impl!{sym Nrexc, Not, Exc}
95path_impl!{sym Rexc, Not, Nexc}
96path_impl!{sym Nexc, Not, Rexc}
97
98macro_rules! nat_impl {
99    ($t:ident) => {
100        path_impl!{sym Add<$t>, Even<$t>, Eq<bool>}
101        path_impl!{sym Add<$t>, Odd<$t>, Xor}
102    };
103}
104
105nat_impl!{u8}
106nat_impl!{u16}
107nat_impl!{u32}
108nat_impl!{u64}