1use crate::Token;
2use alloc::vec::Vec;
3use core::fmt::{self, Display};
4
5#[derive(Clone, Debug)]
7pub enum Command<C, V, Tm> {
8 Intro(C, Vec<(V, Tm)>, Intro<Tm>),
10 Rules(Vec<Rule<V, Tm>>),
12}
13
14#[derive(Clone, Debug)]
16pub enum Intro<Ty, Tm = Ty> {
17 Definition(Option<Ty>, Option<Tm>),
18 Theorem(Ty, Tm),
19 Declaration(Ty),
20}
21
22#[derive(Clone, Debug)]
24pub struct Rule<V, Tm> {
25 pub ctx: Vec<(V, Option<Tm>)>,
27 pub lhs: Tm,
29 pub rhs: Tm,
31}
32
33impl<C, V, Tm> Command<C, V, Tm> {
34 pub fn map_const<C2>(self, f: impl FnOnce(C) -> C2) -> Command<C2, V, Tm> {
36 match self {
37 Self::Intro(x, args, it) => Command::Intro(f(x), args, it),
38 Self::Rules(rules) => Command::Rules(rules),
39 }
40 }
41}
42
43impl<Ty, Tm> Intro<Ty, Tm> {
44 pub fn rewritable(&self) -> bool {
46 match self {
47 Self::Definition(..) => true,
48 Self::Declaration(_) | Self::Theorem(..) => false,
49 }
50 }
51
52 pub fn map_type<U>(self, f: impl FnOnce(Ty) -> U) -> Intro<U, Tm> {
54 match self {
55 Self::Definition(ty, tm) => Intro::Definition(ty.map(f), tm),
56 Self::Theorem(ty, tm) => Intro::Theorem(f(ty), tm),
57 Self::Declaration(ty) => Intro::Declaration(f(ty)),
58 }
59 }
60
61 pub fn map_term<U>(self, f: impl FnOnce(Tm) -> U) -> Intro<Ty, U> {
63 match self {
64 Self::Definition(ty, tm) => Intro::Definition(ty, tm.map(f)),
65 Self::Theorem(ty, tm) => Intro::Theorem(ty, f(tm)),
66 Self::Declaration(ty) => Intro::Declaration(ty),
67 }
68 }
69}
70
71impl<C: Display, V: Display, Tm: Display> Display for Command<C, V, Tm> {
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73 match self {
74 Self::Intro(x, args, it) => {
75 match it {
76 Intro::Theorem(_, _) => write!(f, "thm ")?,
77 Intro::Definition(_, _) => write!(f, "def ")?,
78 Intro::Declaration(_) => (),
79 };
80 write!(f, "{}", x)?;
81 args.iter()
82 .try_for_each(|(x, ty)| write!(f, " ({} : {})", x, ty))?;
83 match it {
84 Intro::Definition(ty, tm) => {
85 ty.iter().try_for_each(|ty| write!(f, " : {}", ty))?;
86 tm.iter().try_for_each(|tm| write!(f, " := {}", tm))
87 }
88 Intro::Theorem(ty, tm) => write!(f, " : {} := {}", ty, tm),
89 Intro::Declaration(ty) => write!(f, " : {}", ty),
90 }
91 }
92 Self::Rules(rules) => rules.iter().try_for_each(|rule| rule.fmt(f)),
93 }
94 }
95}
96
97impl<V: Display, Tm: Display> Display for Rule<V, Tm> {
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 write!(f, "[")?;
100 let mut ctx = self.ctx.iter().peekable();
101 while let Some((x, ty)) = ctx.next() {
102 write!(f, "{}", x)?;
103 ty.iter().try_for_each(|ty| write!(f, ": {}", ty))?;
104 ctx.peek().iter().try_for_each(|_| write!(f, ", "))?;
105 }
106 write!(f, "] {} --> {}", self.lhs, self.rhs)
107 }
108}
109
110#[derive(Debug)]
111pub(crate) enum DefThm {
112 Def,
113 Thm,
114}
115
116#[derive(Debug)]
117pub(crate) enum OfEq {
118 Of,
119 Eq,
120}
121
122#[derive(Debug)]
123pub struct RuleCtx<V, Tm> {
124 rules: Vec<Rule<V, Tm>>,
125 vars: Vec<Option<Tm>>,
126}
127
128impl<V, Tm> Default for RuleCtx<V, Tm> {
129 fn default() -> Self {
130 Self {
131 rules: Default::default(),
132 vars: Default::default(),
133 }
134 }
135}
136
137impl<V, Tm> RuleCtx<V, Tm> {
138 fn add(mut self, bound: &mut Vec<V>, lhs: Tm, rhs: Tm) -> Self {
139 let ctx = core::mem::take(&mut self.vars);
140 let ctx = bound.drain(..).zip(ctx).collect();
141 self.rules.push(Rule { ctx, lhs, rhs });
142 self
143 }
144}
145
146#[derive(Debug, PartialEq)]
148pub enum Error {
149 ExpectedColon,
150 ExpectedColonEq,
151 ExpectedColonOrColonEq,
152 ExpectedLongArrow,
153 ExpectedIdent,
154 ExpectedCommaOrRBrk,
155 ExpectedRPar,
156 ExpectedCmd,
157 UnexpectedPath,
158 UnexpectedToken,
159}
160
161type Result<T> = core::result::Result<T, Error>;
162
163#[derive(Debug)]
165pub(crate) enum State<C, V, Tm> {
166 Init,
168
169 Def,
171 Thm,
173
174 Decl(C, bool),
176
177 Args(DefThm, C, Vec<Tm>),
179 ArgsIn(DefThm, C, Vec<Tm>, Option<(V, bool)>),
183 DefThmEq(DefThm, C, Vec<Tm>, Tm),
185
186 DefOfEq(C, Vec<Tm>, OfEq),
188 ThmOf(C, Vec<Tm>),
190
191 RuleCtx(RuleCtx<V, Tm>, Option<(V, bool)>),
195
196 RuleL(RuleCtx<V, Tm>),
198 RuleR(RuleCtx<V, Tm>, Tm),
200
201 Command(Command<C, V, Tm>),
202}
203
204impl<C, V, Tm> Default for State<C, V, Tm> {
205 fn default() -> Self {
206 Self::Init
207 }
208}
209
210pub trait Joker {
211 fn joker() -> Self;
212}
213
214impl<'s> Joker for &'s str {
215 fn joker() -> Self {
216 "_"
217 }
218}
219
220impl Joker for alloc::string::String {
221 fn joker() -> Self {
222 "_".into()
223 }
224}
225
226impl<C, V: Joker, Tm> State<C, V, Tm> {
227 pub fn parse<S>(self, bound: &mut Vec<V>, token: Token<S>) -> Result<State<C, V, Tm>>
228 where
229 S: Into<C> + Into<V>,
230 {
231 match (self, token) {
232 (state, Token::Symb(s)) if s.path.is_empty() => state.apply_name(s.name),
233 (_, Token::Symb(_)) => Err(Error::UnexpectedPath),
234
235 (State::Init, Token::Def) => Ok(State::Def),
237 (State::Init, Token::Thm) => Ok(State::Thm),
238 (State::Init, Token::LBrk) => Ok(State::RuleCtx(Default::default(), None)),
239 (State::Init, _) => Err(Error::ExpectedCmd),
240
241 (State::Decl(s, false), Token::Colon) => Ok(State::Decl(s, true)),
243 (State::Decl(_, false), _) => Err(Error::ExpectedColon),
244
245 (State::Def | State::Thm, _) => Err(Error::ExpectedIdent),
246
247 (State::Args(dt, s, ctx), Token::LPar) => Ok(State::ArgsIn(dt, s, ctx, None)),
249
250 (State::Args(DefThm::Thm, s, c), Token::Colon) => Ok(State::ThmOf(s, c)),
252 (State::Args(DefThm::Def, s, c), Token::Colon) => Ok(State::DefOfEq(s, c, OfEq::Of)),
254 (State::Args(DefThm::Def, s, c), Token::ColonEq) => Ok(State::DefOfEq(s, c, OfEq::Eq)),
256 (State::Args(DefThm::Thm, _, _), _) => Err(Error::ExpectedColon),
257 (State::Args(DefThm::Def, _, _), _) => Err(Error::ExpectedColonOrColonEq),
258
259 (State::ArgsIn(_, _, _, None), _) => Err(Error::ExpectedIdent),
260
261 (State::ArgsIn(dt, s, c, Some((x, false))), Token::Colon) => {
263 Ok(State::ArgsIn(dt, s, c, Some((x, true))))
264 }
265 (State::ArgsIn(_, _, _, Some((_, false))), _) => Err(Error::ExpectedColon),
266
267 (State::RuleCtx(c, None), Token::RBrk) => Ok(Self::rulel(bound, c)),
269 (State::RuleCtx(_, None), _) => Err(Error::ExpectedCommaOrRBrk),
270
271 (State::RuleCtx(c, Some((x, false))), Token::Colon) => {
273 Ok(State::RuleCtx(c, Some((x, true))))
274 }
275 (State::RuleCtx(mut c, Some((s, false))), Token::Comma) => {
277 bound.push(s);
278 c.vars.push(None);
279 Ok(State::RuleCtx(c, None))
280 }
281 (State::RuleCtx(mut c, Some((s, false))), Token::RBrk) => {
283 bound.push(s);
284 c.vars.push(None);
285 Ok(Self::rulel(bound, c))
286 }
287 (State::RuleCtx(_, Some((_, false))), _) => Err(Error::ExpectedCommaOrRBrk),
289
290 _ => Err(Error::UnexpectedToken),
291 }
292 }
293
294 pub fn apply_name(self, name: impl Into<C> + Into<V>) -> Result<State<C, V, Tm>> {
295 match self {
296 State::Init => Ok(State::Decl(name.into(), false)),
297 State::Def => Ok(State::Args(DefThm::Def, name.into(), Vec::new())),
299 State::Thm => Ok(State::Args(DefThm::Thm, name.into(), Vec::new())),
300 State::ArgsIn(dt, s, c, None) => {
302 Ok(State::ArgsIn(dt, s, c, Some((name.into(), false))))
303 }
304 State::RuleCtx(c, None) => Ok(State::RuleCtx(c, Some((name.into(), false)))),
306 _ => Err(Error::UnexpectedToken),
307 }
308 }
309
310 pub fn expects_term(&self) -> bool {
311 matches!(
312 self,
313 State::Decl(_, true)
314 | State::ThmOf(..)
315 | State::DefOfEq(..)
316 | State::DefThmEq(..)
317 | State::ArgsIn(.., Some((_, true)))
318 | State::RuleCtx(_, Some((_, true)))
319 | State::RuleL(_)
320 | State::RuleR(..)
321 )
322 }
323
324 pub fn rulel(bound: &mut Vec<V>, ctx: RuleCtx<V, Tm>) -> Self {
325 bound.insert(0, V::joker());
326 Self::RuleL(ctx)
327 }
328
329 pub fn apply<S>(self, bound: &mut Vec<V>, tm: Tm, token: Token<S>) -> Result<State<C, V, Tm>> {
330 match (self, token) {
331 (State::ArgsIn(dt, s, mut ctx, Some((x, true))), Token::RPar) => {
332 bound.push(x);
333 ctx.push(tm);
334 Ok(State::Args(dt, s, ctx))
335 }
336
337 (State::RuleL(ctx), Token::LongArrow) => {
338 bound.remove(0);
340 Ok(State::RuleR(ctx, tm))
341 }
342 (State::RuleL(..), _) => Err(Error::ExpectedLongArrow),
343 (State::RuleR(ctx, lhs), Token::LBrk) => {
344 Ok(State::RuleCtx(ctx.add(bound, lhs, tm), None))
345 }
346 (State::RuleCtx(mut ctx, Some((s, true))), Token::RBrk) => {
347 bound.push(s);
348 ctx.vars.push(Some(tm));
349 Ok(Self::rulel(bound, ctx))
350 }
351 (State::RuleCtx(mut ctx, Some((s, true))), Token::Comma) => {
352 bound.push(s);
353 ctx.vars.push(Some(tm));
354 Ok(State::RuleCtx(ctx, None))
355 }
356 (State::RuleCtx(..), _) => Err(Error::ExpectedCommaOrRBrk),
357 (State::ThmOf(x, ctx), Token::ColonEq) => Ok(State::DefThmEq(DefThm::Thm, x, ctx, tm)),
358 (State::DefOfEq(x, ctx, OfEq::Of), Token::ColonEq) => {
359 Ok(State::DefThmEq(DefThm::Def, x, ctx, tm))
360 }
361 (State::ThmOf(..), _) => Err(Error::ExpectedColonEq),
362
363 (State::ArgsIn(_, _, _, Some((_, true))), _) => Err(Error::ExpectedRPar),
364
365 (cur, Token::Dot) => Ok(State::Command(cur.close(bound, tm)?)),
366 _ => Err(Error::UnexpectedToken),
367 }
368 }
369
370 fn close(self, bound: &mut Vec<V>, tm: Tm) -> Result<Command<C, V, Tm>> {
371 match self {
372 State::Decl(x, true) => Ok(Command::Intro(x, Vec::new(), Intro::Declaration(tm))),
373 State::DefOfEq(x, ctx, ofeq) => {
374 let it = match ofeq {
375 OfEq::Eq => Intro::Definition(None, Some(tm)),
376 OfEq::Of => Intro::Definition(Some(tm), None),
377 };
378 let ctx = bound.drain(..).zip(ctx).collect();
379 Ok(Command::Intro(x, ctx, it))
380 }
381 State::DefThmEq(dt, x, ctx, ty) => {
382 let it = match dt {
383 DefThm::Thm => Intro::Theorem(ty, tm),
384 DefThm::Def => Intro::Definition(Some(ty), Some(tm)),
385 };
386 let ctx = bound.drain(..).zip(ctx).collect();
387 Ok(Command::Intro(x, ctx, it))
388 }
389 State::RuleR(ctx, lhs) => Ok(Command::Rules(ctx.add(bound, lhs, tm).rules)),
390 _ => Err(Error::ExpectedCmd),
391 }
392 }
393}