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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use std::cmp::Ordering;
use std::fmt;
use std::ops;
mod arith;
mod order;
#[derive(Debug, Clone)]
pub struct Surreal {
left: Vec<Surreal>,
right: Vec<Surreal>,
}
impl Surreal {
pub fn new(left: Vec<&Surreal>, right: Vec<&Surreal>) -> Surreal {
for xl in &left {
for xr in &right {
if order::leq(xr, xl) {
panic!("Items in the left set must be less than items in the right set");
}
}
}
Surreal {
left: order::cnv(left),
right: order::cnv(right),
}
}
pub fn left(&self) -> Vec<Surreal> {
self.left.clone()
}
pub fn right(&self) -> Vec<Surreal> {
self.right.clone()
}
}
impl PartialEq for Surreal {
fn eq(&self, other: &Surreal) -> bool {
order::leq(self, other) && order::leq(other, self)
}
}
impl Eq for Surreal {}
impl PartialOrd for Surreal {
fn partial_cmp(&self, other: &Surreal) -> Option<Ordering> {
if !order::leq(self, other) {
Some(Ordering::Greater)
} else if !order::leq(other, self) {
Some(Ordering::Less)
} else {
Some(Ordering::Equal)
}
}
}
impl<'a, 'b> ops::Add<&'b Surreal> for &'a Surreal {
type Output = Surreal;
fn add(self, other: &'b Surreal) -> Surreal {
arith::add(self, other)
}
}
impl<'a, 'b> ops::Mul<&'b Surreal> for &'a Surreal {
type Output = Surreal;
fn mul(self, other: &'b Surreal) -> Surreal {
arith::mul(self, other)
}
}
impl<'a> ops::Neg for &'a Surreal {
type Output = Surreal;
fn neg(self) -> Surreal {
arith::neg(self)
}
}
impl<'a, 'b> ops::Sub<&'b Surreal> for &'a Surreal {
type Output = Surreal;
fn sub(self, other: &'b Surreal) -> Surreal {
arith::add(self, &arith::neg(other))
}
}
impl fmt::Display for Surreal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:#?}", self)
}
}