adic/math/normed/
valuation.rs1use std::{
2 cmp::Ordering,
3 fmt::{Debug, Display, Formatter, Result as fmtResult},
4 hash::Hash,
5 ops,
6};
7use num::Zero;
8use super::ValuationRing;
9
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub enum Valuation<F>
37where F: ValuationRing {
38 PosInf,
40 Finite(F),
42}
43
44impl<F> Valuation<F>
45where F: ValuationRing {
46
47 pub fn finite(&self) -> Option<F> {
49 if let Self::Finite(v) = self {
50 Some(*v)
51 } else {
52 None
53 }
54 }
55
56 pub fn is_finite(&self) -> bool {
58 matches!(self, Self::Finite(_))
59 }
60
61 pub fn convert<G>(self) -> Result<Valuation<G>, G::Error>
66 where G: ValuationRing + TryFrom<F> {
67 match self {
68 Valuation::PosInf => Ok(Valuation::PosInf),
69 Valuation::Finite(fval) => Ok(Valuation::Finite(fval.try_into()?)),
70 }
71 }
72
73}
74
75
76impl<F> From<F> for Valuation<F>
77where F: ValuationRing {
78 fn from(value: F) -> Self {
79 Valuation::Finite(value)
80 }
81}
82
83
84impl<F> Zero for Valuation<F>
85where F: ValuationRing {
86 fn zero() -> Self {
87 Self::Finite(F::zero())
88 }
89 fn is_zero(&self) -> bool {
90 *self == Self::Finite(F::zero())
91 }
92}
93
94
95impl<F> Ord for Valuation<F>
96where F: ValuationRing {
97 fn cmp(&self, other: &Self) -> Ordering {
98 match (self, other) {
99 (Self::PosInf, Self::PosInf) => Ordering::Equal,
100 (Self::PosInf, Self::Finite(_)) => Ordering::Greater,
101 (Self::Finite(_), Self::PosInf) => Ordering::Less,
102 (Self::Finite(sv), Self::Finite(ov)) => {
103 sv.cmp(ov)
104 },
105 }
106 }
107}
108
109impl<F> PartialOrd for Valuation<F>
110where F: ValuationRing {
111 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
112 Some(self.cmp(other))
113 }
114}
115
116
117impl<F> Display for Valuation<F>
118where F: ValuationRing + Display {
119 fn fmt(&self, f: &mut Formatter) -> fmtResult {
120 match self {
121 Self::PosInf => write!(f, "inf"),
122 Self::Finite(v) => write!(f, "{v}")
123 }
124 }
125}
126
127
128impl<F> Default for Valuation<F>
129where F: ValuationRing + Default {
130 fn default() -> Self {
131 Self::Finite(F::default())
132 }
133}
134
135
136impl<F> ops::Add for Valuation<F>
137where F: ValuationRing {
138 type Output = Self;
139 fn add(self, rhs: Self) -> Self::Output {
140 if let (Self::Finite(sv), Self::Finite(rv)) = (self, rhs) {
141 Self::Finite(sv + rv)
142 } else {
143 Self::PosInf
144 }
145 }
146}
147
148impl<F> ops::Mul for Valuation<F>
149where F: ValuationRing {
150 type Output = Self;
151 fn mul(self, rhs: Self) -> Self::Output {
152 if let (Self::Finite(sv), Self::Finite(rv)) = (self, rhs) {
153 Self::Finite(sv * rv)
154 } else {
155 Self::PosInf
156 }
157 }
158}
159
160impl<F> ops::Neg for Valuation<F>
161where F: ValuationRing + ops::Neg<Output=F> {
162 type Output = Option<Self>;
163 fn neg(self) -> Self::Output {
164 if let Self::Finite(v) = self {
165 Some(Self::Finite(-v))
166 } else {
167 None
168 }
169 }
170}
171
172impl<F> ops::Sub for Valuation<F>
173where F: ValuationRing + ops::Sub<Output=F> {
174 type Output = Option<Self>;
175 fn sub(self, rhs: Self) -> Self::Output {
176 match (self, rhs) {
177 (Self::Finite(sv), Self::Finite(rv)) => Some(Self::Finite(sv - rv)),
178 (Self::PosInf, Self::Finite(_)) => Some(Self::PosInf),
179 _ => None,
180 }
181 }
182}
183
184impl<F> ops::Div for Valuation<F>
185where F: ValuationRing + ops::Div<Output=F> {
186 type Output = Option<Self>;
187 fn div(self, rhs: Self) -> Self::Output {
188 match (self, rhs) {
189 (Self::Finite(sv), Self::Finite(rv)) => Some(Self::Finite(sv / rv)),
190 (Self::PosInf, Self::Finite(rv)) if Self::Finite(rv) > Self::zero() => Some(Self::PosInf),
191 _ => None,
192 }
193 }
194}