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