|
3 | 3 |
|
4 | 4 | //! Core types and abstractions for ECHIDNA theorem proving |
5 | 5 |
|
| 6 | +use crate::types::TypeInfo; |
6 | 7 | use serde::{Deserialize, Serialize}; |
7 | 8 | use std::collections::HashMap; |
8 | 9 | use std::fmt; |
@@ -33,6 +34,17 @@ pub enum Term { |
33 | 34 | body: Box<Term>, |
34 | 35 | }, |
35 | 36 |
|
| 37 | + /// Dependent pair / sum (Sigma type) Σ(x: A). B |
| 38 | + /// |
| 39 | + /// Represents dependent pairs where the type of the second component may |
| 40 | + /// depend on the value of the first. Non-dependent pairs are expressible |
| 41 | + /// as `Sigma { body }` where `body` does not mention `param`. |
| 42 | + Sigma { |
| 43 | + param: String, |
| 44 | + param_type: Box<Term>, |
| 45 | + body: Box<Term>, |
| 46 | + }, |
| 47 | + |
36 | 48 | /// Type universe at level |
37 | 49 | Type(usize), |
38 | 50 |
|
@@ -121,6 +133,13 @@ impl fmt::Display for Term { |
121 | 133 | } => { |
122 | 134 | write!(f, "(Π {}: {}. {})", param, param_type, body) |
123 | 135 | }, |
| 136 | + Term::Sigma { |
| 137 | + param, |
| 138 | + param_type, |
| 139 | + body, |
| 140 | + } => { |
| 141 | + write!(f, "(Σ {}: {}. {})", param, param_type, body) |
| 142 | + }, |
124 | 143 | Term::Type(level) => write!(f, "Type{}", level), |
125 | 144 | Term::Sort(level) => write!(f, "Sort{}", level), |
126 | 145 | Term::Universe(level) => write!(f, "Type{}", level), |
@@ -190,6 +209,26 @@ pub struct Hypothesis { |
190 | 209 |
|
191 | 210 | /// Optional body (for definitions) |
192 | 211 | pub body: Option<Term>, |
| 212 | + |
| 213 | + /// Optional native type-system decoration (multiplicity, effects, modality, |
| 214 | + /// refinement, semiring, …). `None` is semantically equivalent to a plain |
| 215 | + /// unannotated hypothesis — backends that don't understand the decoration |
| 216 | + /// safely ignore it. |
| 217 | + #[serde(default, skip_serializing_if = "Option::is_none")] |
| 218 | + pub type_info: Option<TypeInfo>, |
| 219 | +} |
| 220 | + |
| 221 | +impl Hypothesis { |
| 222 | + /// Construct a plain hypothesis with no type decoration. |
| 223 | + pub fn new(name: impl Into<String>, ty: Term) -> Self { |
| 224 | + Self { name: name.into(), ty, body: None, type_info: None } |
| 225 | + } |
| 226 | + |
| 227 | + /// Attach a [`TypeInfo`] decoration. |
| 228 | + pub fn with_type_info(mut self, info: TypeInfo) -> Self { |
| 229 | + self.type_info = Some(info); |
| 230 | + self |
| 231 | + } |
193 | 232 | } |
194 | 233 |
|
195 | 234 | /// Proof context with available premises |
@@ -223,13 +262,47 @@ pub struct Definition { |
223 | 262 | pub name: String, |
224 | 263 | pub ty: Term, |
225 | 264 | pub body: Term, |
| 265 | + |
| 266 | + /// Optional native type-system decoration (see [`TypeInfo`]). |
| 267 | + #[serde(default, skip_serializing_if = "Option::is_none")] |
| 268 | + pub type_info: Option<TypeInfo>, |
| 269 | +} |
| 270 | + |
| 271 | +impl Definition { |
| 272 | + /// Construct a plain definition with no type decoration. |
| 273 | + pub fn new(name: impl Into<String>, ty: Term, body: Term) -> Self { |
| 274 | + Self { name: name.into(), ty, body, type_info: None } |
| 275 | + } |
| 276 | + |
| 277 | + /// Attach a [`TypeInfo`] decoration. |
| 278 | + pub fn with_type_info(mut self, info: TypeInfo) -> Self { |
| 279 | + self.type_info = Some(info); |
| 280 | + self |
| 281 | + } |
226 | 282 | } |
227 | 283 |
|
228 | 284 | /// A variable declaration |
229 | 285 | #[derive(Debug, Clone, Serialize, Deserialize)] |
230 | 286 | pub struct Variable { |
231 | 287 | pub name: String, |
232 | 288 | pub ty: Term, |
| 289 | + |
| 290 | + /// Optional native type-system decoration (see [`TypeInfo`]). |
| 291 | + #[serde(default, skip_serializing_if = "Option::is_none")] |
| 292 | + pub type_info: Option<TypeInfo>, |
| 293 | +} |
| 294 | + |
| 295 | +impl Variable { |
| 296 | + /// Construct a plain variable with no type decoration. |
| 297 | + pub fn new(name: impl Into<String>, ty: Term) -> Self { |
| 298 | + Self { name: name.into(), ty, type_info: None } |
| 299 | + } |
| 300 | + |
| 301 | + /// Attach a [`TypeInfo`] decoration. |
| 302 | + pub fn with_type_info(mut self, info: TypeInfo) -> Self { |
| 303 | + self.type_info = Some(info); |
| 304 | + self |
| 305 | + } |
233 | 306 | } |
234 | 307 |
|
235 | 308 | /// A proof tactic/command |
|
0 commit comments