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
use std::fmt;
use std::cmp::Ordering;
use memory::*;
use dispatch::*;
use handle::Handle;
use integral;
use std::fmt::Debug;
pub struct Rational_ { }
pub fn prism_unit() -> Unit { mechanism::prism::<Rational_>() }
pub fn is_prism(prism: AnchoredLine) -> bool { prism[0] == prism_unit() }
pub fn find_prism(h: Handle) -> Option<AnchoredLine> { h.find_prism(prism_unit()) }
pub fn is_rational(h: Handle) -> bool { find_prism(h).is_some() }
pub fn new(top: Handle, bot: Handle) -> Handle {
assert!(integral::is_integral(top));
assert!(integral::is_integral(bot));
let s = Segment::new(3 );
s.set(0, prism_unit());
s.set(1, top.unit());
s.set(2, bot.unit());
s.unit().handle()
}
pub fn new_from_i64(top: i64, bot: i64) -> Handle {
new(integral::new(top).handle(), integral::new(bot).handle())
}
pub fn parse(negate: bool, top: &[u8], bot: &[u8]) -> Handle {
let mut x = 0i64;
for b in top.iter() {
if *b == b'_' {
continue
}
x = x * 10 + (*b - b'0') as i64;
}
let mut y = 0i64;
for b in bot.iter() {
if *b == b'_' {
continue
}
y = y * 10 + (*b - b'0') as i64;
}
if negate { x = -x; }
new_from_i64(x, y)
}
impl Dispatch for Rational_ { }
impl Identification for Rational_ {
fn type_name(&self) -> &'static str { "Rational" }
}
impl Distinguish for Rational_ {
fn hash(&self, prism: AnchoredLine) -> u32 {
use random::{PI, cycle_abc};
let x = cycle_abc(75, PI[212].wrapping_add(prism[1].handle().hash() as u64));
let z = cycle_abc(57, x.wrapping_add(prism[2].handle().hash() as u64));
z as u32
}
fn eq(&self, prism: AnchoredLine, other: Unit) -> bool {
let o = other.handle();
if let Some(o_rat) = find_prism(o) {
prism[1].handle() == o_rat[1].handle() &&
prism[2].handle() == o_rat[2].handle()
} else {
false
}
}
}
impl Aggregate for Rational_ { }
impl Sequential for Rational_ { }
impl Associative for Rational_ { }
impl Reversible for Rational_ {}
impl Sorted for Rational_ {}
impl Notation for Rational_ {
fn edn(&self, prism: AnchoredLine, f: &mut fmt::Formatter) -> fmt::Result {
prism[1].handle().fmt(f)?;
write!(f, "/")?;
prism[2].handle().fmt(f)
}
}
impl Numeral for Rational_ { }
impl Callable for Rational_ { }
#[cfg(test)]
mod tests {
use super::*;
}