1use crate::prelude::*;
2
3fn chain_link_infix_latex(prop: &str) -> Option<&'static str> {
4 if prop == EQUAL {
5 Some("=")
6 } else if prop == NOT_EQUAL {
7 Some(r"\neq")
8 } else if prop == LESS {
9 Some("<")
10 } else if prop == GREATER {
11 Some(">")
12 } else if prop == LESS_EQUAL {
13 Some(r"\leq")
14 } else if prop == GREATER_EQUAL {
15 Some(r"\geq")
16 } else if prop == IN {
17 Some(r"\in")
18 } else {
19 None
20 }
21}
22
23fn latex_escape_underscore(s: &str) -> String {
24 s.replace('_', r"\_")
25}
26
27fn latex_local_ident(name: &str) -> String {
28 format!(r"\mathit{{{}}}", latex_escape_underscore(name))
29}
30
31fn latex_texttt_escape(s: &str) -> String {
32 let mut out = String::new();
33 for ch in s.chars() {
34 match ch {
35 '_' | '%' | '#' | '&' | '$' => {
36 out.push('\\');
37 out.push(ch);
38 }
39 '{' => out.push_str(r"\{"),
40 '}' => out.push_str(r"\}"),
41 '\\' => out.push_str(r"\textbackslash{}"),
42 '^' => out.push_str(r"\textasciicircum{}"),
43 '~' => out.push_str(r"\textasciitilde{}"),
44 _ => out.push(ch),
45 }
46 }
47 out
48}
49
50fn fn_set_clause_latex(clause: &FnSetClause) -> String {
51 let mut slots: Vec<String> = Vec::new();
52 for g in &clause.params_def_with_set {
53 let set = g.set.to_latex_string();
54 for p in &g.params {
55 slots.push(format!(r"{} \in {}", latex_local_ident(p), set));
56 }
57 }
58 let dom = clause
59 .dom_facts
60 .iter()
61 .map(|f| f.to_latex_string())
62 .collect::<Vec<_>>()
63 .join(r", ");
64 let ret = clause.ret_set.to_latex_string();
65 if dom.is_empty() {
66 format!(
67 r"\mathrm{{fn}}\left({}\right)\to {}",
68 slots.join(r", "),
69 ret
70 )
71 } else {
72 format!(
73 r"\mathrm{{fn}}\left({} \,\middle|\, {}\right)\to {}",
74 slots.join(r", "),
75 dom,
76 ret
77 )
78 }
79}
80
81impl AndChainAtomicFact {
82 pub fn to_latex_string(&self) -> String {
83 match self {
84 AndChainAtomicFact::AtomicFact(x) => x.to_latex_string(),
85 AndChainAtomicFact::AndFact(x) => x.to_latex_string(),
86 AndChainAtomicFact::ChainFact(x) => x.to_latex_string(),
87 }
88 }
89}
90
91impl OrAndChainAtomicFact {
92 pub fn to_latex_string(&self) -> String {
93 match self {
94 OrAndChainAtomicFact::AtomicFact(x) => x.to_latex_string(),
95 OrAndChainAtomicFact::AndFact(x) => x.to_latex_string(),
96 OrAndChainAtomicFact::ChainFact(x) => x.to_latex_string(),
97 OrAndChainAtomicFact::OrFact(x) => x.to_latex_string(),
98 }
99 }
100}
101
102impl AndFact {
103 pub fn to_latex_string(&self) -> String {
104 self.facts
105 .iter()
106 .map(|a| a.to_latex_string())
107 .collect::<Vec<_>>()
108 .join(r" \land ")
109 }
110}
111
112impl ChainFact {
113 pub fn to_latex_string(&self) -> String {
114 if self.objs.is_empty() {
115 return String::new();
116 }
117 let mut s = self.objs[0].to_latex_string();
118 for (i, obj) in self.objs[1..].iter().enumerate() {
119 let pname = self.prop_names[i].to_string();
120 let rhs = obj.to_latex_string();
121 if let Some(op) = chain_link_infix_latex(&pname) {
122 s.push(' ');
123 s.push_str(op);
124 s.push(' ');
125 s.push_str(&rhs);
126 } else if is_comparison_str(&pname) {
127 s.push(' ');
128 s.push_str(&pname);
129 s.push(' ');
130 s.push_str(&rhs);
131 } else {
132 s.push_str(&format!(r" \mathrel{{\mathrm{{{}}}}} {}", pname, rhs));
133 }
134 }
135 s
136 }
137}
138
139impl Abs {
140 pub fn to_latex_string(&self) -> String {
141 format!(r"\left| {} \right|", self.arg.to_latex_string())
142 }
143}
144
145impl Add {
146 pub fn to_latex_string(&self) -> String {
147 format!(
148 "{} + {}",
149 self.left.to_latex_string(),
150 self.right.to_latex_string()
151 )
152 }
153}
154
155impl ByCasesStmt {
156 pub fn to_latex_string(&self) -> String {
157 let goal = self
158 .then_facts
159 .iter()
160 .map(|f| f.to_latex_string())
161 .collect::<Vec<_>>()
162 .join(r" \land ");
163 let mut rows: Vec<String> = Vec::new();
164 rows.push(format!(r"\text{{Proof by cases. Goal:}} & {}", goal));
165 for (i, ((case, proof), imposs)) in self
166 .cases
167 .iter()
168 .zip(self.proofs.iter())
169 .zip(self.impossible_facts.iter())
170 .enumerate()
171 {
172 rows.push(format!(
173 r"\textbf{{\text{{Case {}.}}}} & {}",
174 i + 1,
175 case.to_latex_string()
176 ));
177 for st in proof {
178 rows.push(format!(r"& \quad {}", st.to_latex_string()));
179 }
180 if let Some(atom) = imposs {
181 rows.push(format!(
182 r"\textbf{{\text{{Impossible.}}}} & {}",
183 atom.to_latex_string()
184 ));
185 }
186 }
187 format!(
188 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
189 rows.join(" \\\\\n")
190 )
191 }
192}
193
194impl ByContraStmt {
195 pub fn to_latex_string(&self) -> String {
196 let goal = self.to_prove.to_latex_string();
197 let mut rows = vec![format!(
198 r"\text{{Proof by contradiction. Goal:}} & {}",
199 goal
200 )];
201 for st in &self.proof {
202 rows.push(format!(r"& \quad {}", st.to_latex_string()));
203 }
204 rows.push(format!(
205 r"\textbf{{\text{{Contradiction.}}}} & {}",
206 self.impossible_fact.to_latex_string()
207 ));
208 format!(
209 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
210 rows.join(" \\\\\n")
211 )
212 }
213}
214
215impl ByEnumerateClosedRangeStmt {
216 pub fn to_latex_string(&self) -> String {
217 let a = self.closed_range.start.to_latex_string();
218 let b = self.closed_range.end.to_latex_string();
219 let x = self.element.to_latex_string();
220 let row1 = format!(
221 r"&\text{{\textbf{{By enumeration}} on the closed integer interval }} [\![ {0},{1}]\!]\text{{.}}",
222 a, b
223 );
224 let row2 = format!(
225 r"&\text{{Equivalently }} {0} \in \{{{1},\, {1}+1,\, \ldots,\, {2}\}}\text{{ (segment {1}\ldots {2}).}}",
226 x, a, b
227 );
228 let row3 = format!(
229 r"&\text{{So }} {0}={1}\lor {0}={1}+1\lor\cdots\lor {0}={2}\text{{.}}",
230 x, a, b
231 );
232 format!("\\begin{{aligned}}\n{row1} \\\\\n{row2} \\\\\n{row3} \n\\end{{aligned}}")
233 }
234}
235
236impl ByEnumerateFiniteSetStmt {
237 pub fn to_latex_string(&self) -> String {
238 let mut rows = vec![format!(
239 r"\text{{Proof by exhaustive enumeration (finite cases).}} & {}",
240 self.forall_fact.to_latex_string()
241 )];
242 for st in &self.proof {
243 rows.push(format!(r"& \quad {}", st.to_latex_string()));
244 }
245 format!(
246 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
247 rows.join(" \\\\\n")
248 )
249 }
250}
251
252impl ByExtensionStmt {
253 pub fn to_latex_string(&self) -> String {
254 let l = self.left.to_latex_string();
255 let r = self.right.to_latex_string();
256 let mut rows = vec![format!(
257 r"\text{{\textbf{{By extensionality}}:}} & {}={} \Longleftrightarrow \bigl({}\subseteq {}\land {}\subseteq {}\bigr)\text{{.}}",
258 l, r, l, r, r, l
259 )];
260 for st in &self.proof {
261 rows.push(format!(r"& \quad {}", st.to_latex_string()));
262 }
263 format!(
264 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
265 rows.join(" \\\\\n")
266 )
267 }
268}
269
270impl ByFamilyStmt {
271 pub fn to_latex_string(&self) -> String {
272 format!(
273 "\\begin{{aligned}}\n\\text{{\\textbf{{By family}}:}} & \\text{{Use the set-theoretic definition of }} {}\\text{{; obtain the corresponding set characterization.}}\n\\end{{aligned}}",
274 self.family_obj.to_latex_string()
275 )
276 }
277}
278
279impl ByFiniteSeqSetStmt {
280 pub fn to_latex_string(&self) -> String {
281 let o: Obj = self.finite_seq_set.clone().into();
282 format!(
283 "\\begin{{aligned}}\n\\text{{\\textbf{{By finite sequence space}}:}} & \\text{{Use the set-theoretic definition of }} {}\\text{{; obtain the corresponding set characterization.}}\n\\end{{aligned}}",
284 o.to_latex_string()
285 )
286 }
287}
288
289impl ByFnSetStmt {
290 pub fn to_latex_string(&self) -> String {
291 format!(
292 "\\begin{{aligned}}\n\\text{{\\textbf{{By fn set}}:}} & {} \\in {}\\\\\n& \\quad \\text{{Unfold this membership via the set-theoretic definition of the function space; obtain the corresponding facts.}}\n\\end{{aligned}}",
293 self.func.to_latex_string(),
294 self.fn_set.to_latex_string()
295 )
296 }
297}
298
299impl ByFnStmt {
300 pub fn to_latex_string(&self) -> String {
301 format!(
302 "\\begin{{aligned}}\n\\text{{\\textbf{{By fn}}:}} & \\text{{Use the graph / function definition of }} {}\\text{{.}}\n\\end{{aligned}}",
303 self.function.to_latex_string()
304 )
305 }
306}
307
308impl ByForStmt {
309 pub fn to_latex_string(&self) -> String {
310 let mut rows = vec![format!(
311 r"\text{{\textbf{{by for}}:}} & {}",
312 self.forall_fact.to_latex_string()
313 )];
314 for st in &self.proof {
315 rows.push(format!(r"& \quad {}", st.to_latex_string()));
316 }
317 format!(
318 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
319 rows.join(" \\\\\n")
320 )
321 }
322}
323
324impl ByInducStmt {
325 pub fn to_latex_string(&self) -> String {
326 let goals = self
327 .to_prove
328 .iter()
329 .map(|f| f.to_latex_string())
330 .collect::<Vec<_>>()
331 .join(r" \land ");
332 let induc_label = if self.strong {
333 r"\text{\textbf{strong induc} on }"
334 } else {
335 r"\text{\textbf{by induc} on }"
336 };
337 let mut rows = vec![format!(
338 r"{} {} \text{{ from }} {} \texttt{{:}} & {}",
339 induc_label,
340 latex_local_ident(&self.param),
341 self.induc_from.to_latex_string(),
342 goals
343 )];
344 rows.push(r"\text{prove:} &".to_string());
345 for st in &self.proof {
346 rows.push(format!(r"& \quad {}", st.to_latex_string()));
347 }
348 format!(
349 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
350 rows.join(" \\\\\n")
351 )
352 }
353}
354
355impl ByMatrixSetStmt {
356 pub fn to_latex_string(&self) -> String {
357 let o: Obj = self.matrix_set.clone().into();
358 format!(
359 "\\begin{{aligned}}\n\\text{{\\textbf{{By matrix space}}:}} & \\text{{Use the set-theoretic definition of }} {}\\text{{; obtain the corresponding set characterization.}}\n\\end{{aligned}}",
360 o.to_latex_string()
361 )
362 }
363}
364
365impl BySeqSetStmt {
366 pub fn to_latex_string(&self) -> String {
367 let o: Obj = self.seq_set.clone().into();
368 format!(
369 "\\begin{{aligned}}\n\\text{{\\textbf{{By sequence space}}:}} & \\text{{Use the set-theoretic definition of }} {}\\text{{; obtain the corresponding set characterization.}}\n\\end{{aligned}}",
370 o.to_latex_string()
371 )
372 }
373}
374
375impl ByTupleStmt {
376 pub fn to_latex_string(&self) -> String {
377 format!(
378 "\\begin{{aligned}}\n\\text{{\\textbf{{By tuple}}:}} & \\text{{Use the set-theoretic ordered-pair / tuple encoding for }} {}\\text{{; obtain the corresponding set-theoretic facts.}}\n\\end{{aligned}}",
379 self.obj.to_latex_string()
380 )
381 }
382}
383
384impl Cap {
385 pub fn to_latex_string(&self) -> String {
386 format!(
387 r"\operatorname{{{}}}\left( {}\right)",
388 CAP,
389 self.left.to_latex_string()
390 )
391 }
392}
393
394impl Cart {
395 pub fn to_latex_string(&self) -> String {
396 let inner = self
397 .args
398 .iter()
399 .map(|o| o.to_latex_string())
400 .collect::<Vec<_>>()
401 .join(", ");
402 format!(r"\operatorname{{{}}}\left( {}\right)", CART, inner)
403 }
404}
405
406impl CartDim {
407 pub fn to_latex_string(&self) -> String {
408 format!(
409 r"\operatorname{{{}}}\left( {}\right)",
410 CART_DIM,
411 self.set.to_latex_string()
412 )
413 }
414}
415
416impl ClaimStmt {
417 pub fn to_latex_string(&self) -> String {
418 let mut rows = vec![
419 format!(
420 r"\text{{\textbf{{claim}}:}} & {}",
421 self.fact.to_latex_string()
422 ),
423 r"\text{\textbf{prove}:} &".to_string(),
424 ];
425 for st in &self.proof {
426 rows.push(format!(r"& \quad {}", st.to_latex_string()));
427 }
428 format!(
429 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
430 rows.join(" \\\\\n")
431 )
432 }
433}
434
435impl ClosedRange {
436 pub fn to_latex_string(&self) -> String {
437 format!(
438 r"\operatorname{{{}}}\left( {}, {} \right)",
439 CLOSED_RANGE,
440 self.start.to_latex_string(),
441 self.end.to_latex_string()
442 )
443 }
444}
445
446impl Count {
447 pub fn to_latex_string(&self) -> String {
448 format!(
449 r"\operatorname{{{}}}\left( {}\right)",
450 COUNT,
451 self.set.to_latex_string()
452 )
453 }
454}
455
456impl Sum {
457 pub fn to_latex_string(&self) -> String {
458 format!(
459 r"\operatorname{{{}}}\left( {}, {}, {} \right)",
460 SUM,
461 self.start.to_latex_string(),
462 self.end.to_latex_string(),
463 self.func.to_latex_string()
464 )
465 }
466}
467
468impl Product {
469 pub fn to_latex_string(&self) -> String {
470 format!(
471 r"\operatorname{{{}}}\left( {}, {}, {} \right)",
472 PRODUCT,
473 self.start.to_latex_string(),
474 self.end.to_latex_string(),
475 self.func.to_latex_string()
476 )
477 }
478}
479
480impl Cup {
481 pub fn to_latex_string(&self) -> String {
482 format!(
483 r"\operatorname{{{}}}\left( {}\right)",
484 CUP,
485 self.left.to_latex_string()
486 )
487 }
488}
489
490impl Choose {
491 pub fn to_latex_string(&self) -> String {
492 format!(
493 r"\operatorname{{{}}}\left( {}\right)",
494 CHOOSE,
495 self.set.to_latex_string()
496 )
497 }
498}
499
500impl DefAbstractPropStmt {
501 pub fn to_latex_string(&self) -> String {
502 let ps = self
503 .params
504 .iter()
505 .map(|p| latex_local_ident(p))
506 .collect::<Vec<_>>()
507 .join(", ");
508 format!(
509 r"\operatorname{{{}}}\, {}\left\{{ {} \right\}}",
510 ABSTRACT_PROP,
511 latex_local_ident(&self.name),
512 ps
513 )
514 }
515}
516
517impl DefAlgoStmt {
518 pub fn to_latex_string(&self) -> String {
519 let ps = self
520 .params
521 .iter()
522 .map(|p| latex_local_ident(p))
523 .collect::<Vec<_>>()
524 .join(", ");
525 let mut rows = vec![format!(
526 r"\operatorname{{{}}}\, {}\left( {}\right) \texttt{{:}}",
527 ALGO,
528 latex_local_ident(&self.name),
529 ps
530 )];
531 for c in &self.cases {
532 rows.push(format!(
533 r"& \quad \mathrm{{case}}\ {} \texttt{{:}}\ {}",
534 c.condition.to_latex_string(),
535 c.return_stmt.value.to_latex_string()
536 ));
537 }
538 if let Some(dr) = &self.default_return {
539 rows.push(format!(
540 r"& \quad \mathrm{{default}}\ \texttt{{:}}\ {}",
541 dr.value.to_latex_string()
542 ));
543 }
544 format!(
545 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
546 rows.join(" \\\\\n")
547 )
548 }
549}
550
551impl DefFamilyStmt {
552 pub fn to_latex_string(&self) -> String {
553 let dom = self
554 .dom_facts
555 .iter()
556 .map(|f| f.to_latex_string())
557 .collect::<Vec<_>>()
558 .join(r", ");
559 format!(
560 r"\operatorname{{{}}}\, {}\left( {} : {} \right) = {}",
561 FAMILY,
562 latex_local_ident(&self.name),
563 self.params_def_with_type.to_latex_string(),
564 dom,
565 self.equal_to.to_latex_string()
566 )
567 }
568}
569
570impl DefLetStmt {
571 pub fn to_latex_string(&self) -> String {
572 match self.facts.len() {
573 0 => format!(
574 r"\operatorname{{{}}}\, {}",
575 LET,
576 self.param_def.to_latex_string()
577 ),
578 _ => {
579 let mut rows = vec![format!(
580 r"\operatorname{{{}}}\, {}",
581 LET,
582 self.param_def.to_latex_string()
583 )];
584 for fact in &self.facts {
585 rows.push(format!(r"& \quad {}", fact.to_latex_string()));
586 }
587 format!(
588 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
589 rows.join(" \\\\\n")
590 )
591 }
592 }
593 }
594}
595
596impl DefPropStmt {
597 pub fn to_latex_string(&self) -> String {
598 match self.iff_facts.len() {
599 0 => format!(
600 r"\operatorname{{{}}}\, {}\left\{{ {} \right\}}",
601 PROP,
602 latex_local_ident(&self.name),
603 self.params_def_with_type.to_latex_string()
604 ),
605 _ => {
606 let mut rows = vec![format!(
607 r"\operatorname{{{}}}\, {}\left\{{ {} \right\}} \texttt{{:}}",
608 PROP,
609 latex_local_ident(&self.name),
610 self.params_def_with_type.to_latex_string()
611 )];
612 for fact in &self.iff_facts {
613 rows.push(format!(r"& \quad {}", fact.to_latex_string()));
614 }
615 format!(
616 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
617 rows.join(" \\\\\n")
618 )
619 }
620 }
621 }
622}
623
624impl Div {
625 pub fn to_latex_string(&self) -> String {
626 format!(
627 r"\frac{{{}}}{{{}}}",
628 self.left.to_latex_string(),
629 self.right.to_latex_string()
630 )
631 }
632}
633
634impl DoNothingStmt {
635 pub fn to_latex_string(&self) -> String {
636 format!(r"\mathrm{{{}}}", DO_NOTHING)
637 }
638}
639
640impl ClearStmt {
641 pub fn to_latex_string(&self) -> String {
642 format!(r"\mathrm{{{}}}", CLEAR)
643 }
644}
645
646impl EqualFact {
647 pub fn to_latex_string(&self) -> String {
648 format!(
649 "{} = {}",
650 self.left.to_latex_string(),
651 self.right.to_latex_string()
652 )
653 }
654}
655
656impl EvalStmt {
657 pub fn to_latex_string(&self) -> String {
658 format!(
659 r"\operatorname{{{}}}\, {}",
660 EVAL,
661 self.obj_to_eval.to_latex_string()
662 )
663 }
664}
665
666impl ExistFactEnum {
667 pub fn to_latex_string(&self) -> String {
668 let head = if self.is_exist_unique() {
669 r"\exists!"
670 } else {
671 r"\exists"
672 };
673 let params = self.params_def_with_type().to_latex_string();
674 let facts = self
675 .facts()
676 .iter()
677 .map(|f| f.to_latex_string())
678 .collect::<Vec<_>>()
679 .join(r", ");
680 format!(
681 r"{}\, \left( {}\right)\, \mathrm{{st}}\, \left\{{ {} \right\}}",
682 head, params, facts
683 )
684 }
685}
686
687impl ExistOrAndChainAtomicFact {
688 pub fn to_latex_string(&self) -> String {
689 match self {
690 ExistOrAndChainAtomicFact::AtomicFact(x) => x.to_latex_string(),
691 ExistOrAndChainAtomicFact::AndFact(x) => x.to_latex_string(),
692 ExistOrAndChainAtomicFact::ChainFact(x) => x.to_latex_string(),
693 ExistOrAndChainAtomicFact::OrFact(x) => x.to_latex_string(),
694 ExistOrAndChainAtomicFact::ExistFact(x) => x.to_latex_string(),
695 }
696 }
697}
698
699impl FamilyObj {
700 pub fn to_latex_string(&self) -> String {
701 let head = self.name.to_latex_string();
702 let args = self
703 .params
704 .iter()
705 .map(|o| o.to_latex_string())
706 .collect::<Vec<_>>()
707 .join(", ");
708 format!(
709 r"\operatorname{{{}}}\left( {}\right)",
710 head, args
711 )
712 }
713}
714
715impl FiniteSeqListObj {
716 pub fn to_latex_string(&self) -> String {
717 let inner = self
718 .objs
719 .iter()
720 .map(|o| o.to_latex_string())
721 .collect::<Vec<_>>()
722 .join(", ");
723 format!(r"\left[ {} \right]", inner)
724 }
725}
726
727impl FiniteSeqSet {
728 pub fn to_latex_string(&self) -> String {
729 format!(
730 r"\operatorname{{{}}}\left( {}, {} \right)",
731 FINITE_SEQ,
732 self.set.to_latex_string(),
733 self.n.to_latex_string()
734 )
735 }
736}
737
738impl FnObj {
739 pub fn to_latex_string(&self) -> String {
740 let head = match self.head.as_ref() {
741 FnObjHead::Identifier(i) => i.to_latex_string(),
742 FnObjHead::IdentifierWithMod(i) => i.to_latex_string(),
743 FnObjHead::Forall(p) => latex_local_ident(&p.name),
744 FnObjHead::DefHeader(p) => latex_local_ident(&p.name),
745 FnObjHead::Exist(p) => latex_local_ident(&p.name),
746 FnObjHead::SetBuilder(p) => latex_local_ident(&p.name),
747 FnObjHead::FnSet(p) => latex_local_ident(&p.name),
748 FnObjHead::AnonymousFnLiteral(a) => a.to_latex_string(),
749 FnObjHead::Induc(p) => latex_local_ident(&p.name),
750 FnObjHead::DefAlgo(p) => latex_local_ident(&p.name),
751 };
752 let mut s = head;
753 for group in self.body.iter() {
754 let inner = group
755 .iter()
756 .map(|o| o.to_latex_string())
757 .collect::<Vec<_>>()
758 .join(", ");
759 s.push_str(&format!(r"\left( {} \right)", inner));
760 }
761 s
762 }
763}
764
765impl AnonymousFn {
766 pub fn to_latex_string(&self) -> String {
767 let mut slots: Vec<String> = Vec::new();
768 for g in &self.body.params_def_with_set {
769 let set = g.set.to_latex_string();
770 for p in &g.params {
771 slots.push(format!(r"{} \in {}", latex_local_ident(p), set));
772 }
773 }
774 let dom = self
775 .body
776 .dom_facts
777 .iter()
778 .map(|f| f.to_latex_string())
779 .collect::<Vec<_>>()
780 .join(r", ");
781 let ret = self.body.ret_set.to_latex_string();
782 let body = self.equal_to.to_latex_string();
783 let sig = if dom.is_empty() {
784 format!(r"\left({}\right)", slots.join(r", "))
785 } else {
786 format!(
787 r"\left({} \,\middle|\, {}\right)",
788 slots.join(r", "),
789 dom
790 )
791 };
792 format!(
793 r"'\, {} \to {} \mapsto \left\{{ {}\right\}}",
794 sig, ret, body
795 )
796 }
797}
798
799impl FnSet {
800 pub fn to_latex_string(&self) -> String {
801 let mut slots: Vec<String> = Vec::new();
802 for g in &self.body.params_def_with_set {
803 let set = g.set.to_latex_string();
804 for p in &g.params {
805 slots.push(format!(r"{} \in {}", latex_local_ident(p), set));
806 }
807 }
808 let dom = self
809 .body
810 .dom_facts
811 .iter()
812 .map(|f| f.to_latex_string())
813 .collect::<Vec<_>>()
814 .join(r", ");
815 let ret = self.body.ret_set.to_latex_string();
816 if dom.is_empty() {
817 format!(
818 r"\mathrm{{fn}}\left({}\right)\to {}",
819 slots.join(r", "),
820 ret
821 )
822 } else {
823 format!(
824 r"\mathrm{{fn}}\left({} \,\middle|\, {}\right)\to {}",
825 slots.join(r", "),
826 dom,
827 ret
828 )
829 }
830 }
831}
832
833impl ForallFact {
834 pub fn to_latex_string(&self) -> String {
835 let params = self.params_def_with_type.to_latex_string();
836 let then = self
837 .then_facts
838 .iter()
839 .map(|f| f.to_latex_string())
840 .collect::<Vec<_>>()
841 .join(r" \land ");
842 if self.dom_facts.is_empty() {
843 format!(r"\forall \left( {}\right),\, {}", params, then)
844 } else {
845 let dom = self
846 .dom_facts
847 .iter()
848 .map(|f| f.to_latex_string())
849 .collect::<Vec<_>>()
850 .join(r" \land ");
851 format!(
852 r"\forall \left( {}\right),\ \left( {}\right) \Rightarrow \left( {}\right)",
853 params, dom, then
854 )
855 }
856 }
857}
858
859impl ForallFactWithIff {
860 pub fn to_latex_string(&self) -> String {
861 let iff = self
862 .iff_facts
863 .iter()
864 .map(|f| f.to_latex_string())
865 .collect::<Vec<_>>()
866 .join(r" \land ");
867 format!(
868 r"{}\, \Longleftrightarrow\, \left( {}\right)",
869 self.forall_fact.to_latex_string(),
870 iff
871 )
872 }
873}
874
875impl GreaterEqualFact {
876 pub fn to_latex_string(&self) -> String {
877 format!(
878 r"{} \geq {}",
879 self.left.to_latex_string(),
880 self.right.to_latex_string()
881 )
882 }
883}
884
885impl GreaterFact {
886 pub fn to_latex_string(&self) -> String {
887 format!(
888 "{} > {}",
889 self.left.to_latex_string(),
890 self.right.to_latex_string()
891 )
892 }
893}
894
895impl HaveByExistStmt {
896 pub fn to_latex_string(&self) -> String {
897 let names = self
898 .equal_tos
899 .iter()
900 .map(|s| latex_local_ident(s))
901 .collect::<Vec<_>>()
902 .join(", ");
903 format!(
904 r"\mathrm{{have}}\ \mathrm{{by}}\ {} : {}",
905 self.exist_fact_in_have_obj_st.to_latex_string(),
906 names
907 )
908 }
909}
910
911impl HaveFnByInducStmt {
912 pub fn to_latex_string(&self) -> String {
913 let mut rows: Vec<String> = Vec::new();
914 rows.push(format!(
915 r"\mathrm{{have}}\ \mathrm{{fn}}\ \mathrm{{by}}\ \mathrm{{induc}}\ \mathrm{{from}}\ {} \texttt{{:}}\ \mathrm{{fn}}\ {}\left( {} : {} \geq {} \right) {}",
916 self.induc_from.to_latex_string(),
917 latex_local_ident(&self.name),
918 latex_local_ident(&self.param),
919 Z,
920 self.induc_from.to_latex_string(),
921 self.ret_set.to_latex_string()
922 ));
923 for (i, eq) in self.special_cases_equal_tos.iter().enumerate() {
924 rows.push(format!(
925 r"& \quad \mathrm{{case}}\ {} : {}",
926 i,
927 eq.to_latex_string()
928 ));
929 }
930 let n = self.special_cases_equal_tos.len();
931 match &self.last_case {
932 HaveFnByInducLastCase::EqualTo(eq) => {
933 rows.push(format!(
934 r"& \quad \mathrm{{case}}\ \geq {} : {}",
935 n,
936 eq.to_latex_string()
937 ));
938 }
939 HaveFnByInducLastCase::NestedCases(nc) => {
940 rows.push(format!(r"& \quad \mathrm{{case}}\ \geq {} \texttt{{:}}", n));
941 for c in nc {
942 rows.push(format!(
943 r"& \quad \quad \mathrm{{case}}\ {} : {}",
944 c.case_fact.to_latex_string(),
945 c.equal_to.to_latex_string()
946 ));
947 }
948 }
949 }
950 format!(
951 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
952 rows.join(" \\\\\n")
953 )
954 }
955}
956
957impl HaveFnEqualCaseByCaseStmt {
958 pub fn to_latex_string(&self) -> String {
959 let head = format!(
960 r"\mathrm{{have}}\ \mathrm{{fn}}\ {}\ \texttt{{=}} \texttt{{:}}",
961 latex_local_ident(&self.name)
962 );
963 let clause = fn_set_clause_latex(&self.fn_set_clause);
964 let mut rows = vec![format!(r"{} & {}", head, clause)];
965 for (i, case) in self.cases.iter().enumerate() {
966 rows.push(format!(
967 r"& \quad \mathrm{{case}}\ {} \texttt{{:}}\ {} = {}",
968 case.to_latex_string(),
969 latex_local_ident(&self.name),
970 self.equal_tos[i].to_latex_string()
971 ));
972 }
973 format!(
974 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
975 rows.join(" \\\\\n")
976 )
977 }
978}
979
980impl HaveFnEqualStmt {
981 pub fn to_latex_string(&self) -> String {
982 format!(
983 r"\mathrm{{have}}\ \mathrm{{fn}}\ {}\ {} {}",
984 latex_local_ident(&self.name),
985 fn_set_clause_latex(&self.fn_set_clause),
986 self.equal_to.to_latex_string()
987 )
988 }
989}
990
991impl HaveObjEqualStmt {
992 pub fn to_latex_string(&self) -> String {
993 let rhs = self
994 .objs_equal_to
995 .iter()
996 .map(|o| o.to_latex_string())
997 .collect::<Vec<_>>()
998 .join(", ");
999 format!(
1000 r"\mathrm{{have}}\ {} = {}",
1001 self.param_def.to_latex_string(),
1002 rhs
1003 )
1004 }
1005}
1006
1007impl HaveObjInNonemptySetOrParamTypeStmt {
1008 pub fn to_latex_string(&self) -> String {
1009 format!(r"\mathrm{{have}}\ {}", self.param_def.to_latex_string())
1010 }
1011}
1012
1013impl Identifier {
1014 pub fn to_latex_string(&self) -> String {
1015 latex_local_ident(&self.name)
1016 }
1017}
1018
1019impl IdentifierWithMod {
1020 pub fn to_latex_string(&self) -> String {
1021 format!(
1022 r"{}\mathbin{{\mathrm{{::}}}}{}",
1023 latex_local_ident(&self.mod_name),
1024 latex_local_ident(&self.name)
1025 )
1026 }
1027}
1028
1029impl AtomicName {
1030 pub fn to_latex_string(&self) -> String {
1031 match self {
1032 AtomicName::WithoutMod(s) => latex_local_ident(s),
1033 AtomicName::WithMod(m, n) => format!(
1034 r"{}\mathbin{{\mathrm{{::}}}}{}",
1035 latex_local_ident(m),
1036 latex_local_ident(n)
1037 ),
1038 }
1039 }
1040}
1041
1042impl InFact {
1043 pub fn to_latex_string(&self) -> String {
1044 format!(
1045 r"{} \in {}",
1046 self.element.to_latex_string(),
1047 self.set.to_latex_string()
1048 )
1049 }
1050}
1051
1052impl Intersect {
1053 pub fn to_latex_string(&self) -> String {
1054 format!(
1055 r"{} \cap {}",
1056 self.left.to_latex_string(),
1057 self.right.to_latex_string()
1058 )
1059 }
1060}
1061
1062impl IsCartFact {
1063 pub fn to_latex_string(&self) -> String {
1064 format!(
1065 r"\$ \mathrm{{{}}}\left( {}\right)",
1066 IS_CART,
1067 self.set.to_latex_string()
1068 )
1069 }
1070}
1071
1072impl IsFiniteSetFact {
1073 pub fn to_latex_string(&self) -> String {
1074 format!(
1075 r"\$ \mathrm{{{}}}\left( {}\right)",
1076 IS_FINITE_SET,
1077 self.set.to_latex_string()
1078 )
1079 }
1080}
1081
1082impl IsNonemptySetFact {
1083 pub fn to_latex_string(&self) -> String {
1084 format!(
1085 r"\$ \mathrm{{{}}}\left( {}\right)",
1086 IS_NONEMPTY_SET,
1087 self.set.to_latex_string()
1088 )
1089 }
1090}
1091
1092impl IsSetFact {
1093 pub fn to_latex_string(&self) -> String {
1094 format!(
1095 r"\$ \mathrm{{{}}}\left( {}\right)",
1096 IS_SET,
1097 self.set.to_latex_string()
1098 )
1099 }
1100}
1101
1102impl IsTupleFact {
1103 pub fn to_latex_string(&self) -> String {
1104 format!(
1105 r"\$ \mathrm{{{}}}\left( {}\right)",
1106 IS_TUPLE,
1107 self.set.to_latex_string()
1108 )
1109 }
1110}
1111
1112impl KnowStmt {
1113 pub fn to_latex_string(&self) -> String {
1114 if self.facts.len() == 1 {
1115 format!(
1116 r"\operatorname{{{}}} {}",
1117 KNOW,
1118 self.facts[0].to_latex_string()
1119 )
1120 } else {
1121 let rows = self
1122 .facts
1123 .iter()
1124 .map(|fact| format!("& {}", fact.to_latex_string()))
1125 .collect::<Vec<_>>()
1126 .join(" \\\\\n");
1127 format!(
1128 r"\operatorname{{{}}}\colon \begin{{aligned}}{}\end{{aligned}}",
1129 KNOW, rows
1130 )
1131 }
1132 }
1133}
1134
1135impl LessEqualFact {
1136 pub fn to_latex_string(&self) -> String {
1137 format!(
1138 r"{} \leq {}",
1139 self.left.to_latex_string(),
1140 self.right.to_latex_string()
1141 )
1142 }
1143}
1144
1145impl LessFact {
1146 pub fn to_latex_string(&self) -> String {
1147 format!(
1148 "{} < {}",
1149 self.left.to_latex_string(),
1150 self.right.to_latex_string()
1151 )
1152 }
1153}
1154
1155impl ListSet {
1156 pub fn to_latex_string(&self) -> String {
1157 let inner = self
1158 .list
1159 .iter()
1160 .map(|o| o.to_latex_string())
1161 .collect::<Vec<_>>()
1162 .join(", ");
1163 format!(r"\left\{{ {} \right\}}", inner)
1164 }
1165}
1166
1167impl Log {
1168 pub fn to_latex_string(&self) -> String {
1169 format!(
1170 r"\log_{{{}}} \left( {} \right)",
1171 self.base.to_latex_string(),
1172 self.arg.to_latex_string()
1173 )
1174 }
1175}
1176
1177impl MatrixAdd {
1178 pub fn to_latex_string(&self) -> String {
1179 format!(
1180 r"{} \mathbin{{\mathrm{{{}}}}} {}",
1181 self.left.to_latex_string(),
1182 latex_escape_underscore(MATRIX_ADD),
1183 self.right.to_latex_string()
1184 )
1185 }
1186}
1187
1188impl MatrixListObj {
1189 pub fn to_latex_string(&self) -> String {
1190 let rows = self
1191 .rows
1192 .iter()
1193 .map(|row| {
1194 let inner = row
1195 .iter()
1196 .map(|o| o.to_latex_string())
1197 .collect::<Vec<_>>()
1198 .join(", ");
1199 format!(r"\left( {} \right)", inner)
1200 })
1201 .collect::<Vec<_>>()
1202 .join(", ");
1203 format!(r"\left[ {} \right]", rows)
1204 }
1205}
1206
1207impl MatrixMul {
1208 pub fn to_latex_string(&self) -> String {
1209 format!(
1210 r"{} \mathbin{{\mathrm{{{}}}}} {}",
1211 self.left.to_latex_string(),
1212 latex_escape_underscore(MATRIX_MUL),
1213 self.right.to_latex_string()
1214 )
1215 }
1216}
1217
1218impl MatrixPow {
1219 pub fn to_latex_string(&self) -> String {
1220 format!(
1221 r"{} \mathbin{{\mathrm{{{}}}}} {}",
1222 self.base.to_latex_string(),
1223 latex_escape_underscore(MATRIX_POW),
1224 self.exponent.to_latex_string()
1225 )
1226 }
1227}
1228
1229impl MatrixScalarMul {
1230 pub fn to_latex_string(&self) -> String {
1231 format!(
1232 r"{} \mathbin{{\mathrm{{{}}}}} {}",
1233 self.scalar.to_latex_string(),
1234 latex_escape_underscore(MATRIX_SCALAR_MUL),
1235 self.matrix.to_latex_string()
1236 )
1237 }
1238}
1239
1240impl MatrixSet {
1241 pub fn to_latex_string(&self) -> String {
1242 format!(
1243 r"\operatorname{{{}}}\left( {}, {}, {} \right)",
1244 MATRIX,
1245 self.set.to_latex_string(),
1246 self.row_len.to_latex_string(),
1247 self.col_len.to_latex_string()
1248 )
1249 }
1250}
1251
1252impl MatrixSub {
1253 pub fn to_latex_string(&self) -> String {
1254 format!(
1255 r"{} \mathbin{{\mathrm{{{}}}}} {}",
1256 self.left.to_latex_string(),
1257 latex_escape_underscore(MATRIX_SUB),
1258 self.right.to_latex_string()
1259 )
1260 }
1261}
1262
1263impl Max {
1264 pub fn to_latex_string(&self) -> String {
1265 format!(
1266 r"\max \left( {}, {} \right)",
1267 self.left.to_latex_string(),
1268 self.right.to_latex_string()
1269 )
1270 }
1271}
1272
1273impl Min {
1274 pub fn to_latex_string(&self) -> String {
1275 format!(
1276 r"\min \left( {}, {} \right)",
1277 self.left.to_latex_string(),
1278 self.right.to_latex_string()
1279 )
1280 }
1281}
1282
1283impl Mod {
1284 pub fn to_latex_string(&self) -> String {
1285 format!(
1286 r"\left( {} \mathbin{{\mathrm{{mod}}}} {} \right)",
1287 self.left.to_latex_string(),
1288 self.right.to_latex_string()
1289 )
1290 }
1291}
1292
1293impl Mul {
1294 pub fn to_latex_string(&self) -> String {
1295 format!(
1296 r"{0} \cdot {1}",
1297 self.left.to_latex_string(),
1298 self.right.to_latex_string()
1299 )
1300 }
1301}
1302
1303impl NormalAtomicFact {
1304 pub fn to_latex_string(&self) -> String {
1305 let pred = self.predicate.to_latex_string();
1306 let args = self
1307 .body
1308 .iter()
1309 .map(|o| o.to_latex_string())
1310 .collect::<Vec<_>>()
1311 .join(", ");
1312 format!(r"\$ {}\left( {}\right)", pred, args)
1313 }
1314}
1315
1316impl NotEqualFact {
1317 pub fn to_latex_string(&self) -> String {
1318 format!(
1319 r"{} \neq {}",
1320 self.left.to_latex_string(),
1321 self.right.to_latex_string()
1322 )
1323 }
1324}
1325
1326impl NotGreaterEqualFact {
1327 pub fn to_latex_string(&self) -> String {
1328 format!(
1329 r"{} \ngeq {}",
1330 self.left.to_latex_string(),
1331 self.right.to_latex_string()
1332 )
1333 }
1334}
1335
1336impl NotGreaterFact {
1337 pub fn to_latex_string(&self) -> String {
1338 format!(
1339 r"{} \ngtr {}",
1340 self.left.to_latex_string(),
1341 self.right.to_latex_string()
1342 )
1343 }
1344}
1345
1346impl NotInFact {
1347 pub fn to_latex_string(&self) -> String {
1348 format!(
1349 r"{} \notin {}",
1350 self.element.to_latex_string(),
1351 self.set.to_latex_string()
1352 )
1353 }
1354}
1355
1356impl NotIsCartFact {
1357 pub fn to_latex_string(&self) -> String {
1358 format!(
1359 r"\neg \left( \$ \mathrm{{{}}}\left( {}\right) \right)",
1360 IS_CART,
1361 self.set.to_latex_string()
1362 )
1363 }
1364}
1365
1366impl NotIsFiniteSetFact {
1367 pub fn to_latex_string(&self) -> String {
1368 format!(
1369 r"\neg \left( \$ \mathrm{{{}}}\left( {}\right) \right)",
1370 IS_FINITE_SET,
1371 self.set.to_latex_string()
1372 )
1373 }
1374}
1375
1376impl NotIsNonemptySetFact {
1377 pub fn to_latex_string(&self) -> String {
1378 format!(
1379 r"\neg \left( \$ \mathrm{{{}}}\left( {}\right) \right)",
1380 IS_NONEMPTY_SET,
1381 self.set.to_latex_string()
1382 )
1383 }
1384}
1385
1386impl NotIsSetFact {
1387 pub fn to_latex_string(&self) -> String {
1388 format!(
1389 r"\neg \left( \$ \mathrm{{{}}}\left( {}\right) \right)",
1390 IS_SET,
1391 self.set.to_latex_string()
1392 )
1393 }
1394}
1395
1396impl NotIsTupleFact {
1397 pub fn to_latex_string(&self) -> String {
1398 format!(
1399 r"\neg \left( \$ \mathrm{{{}}}\left( {}\right) \right)",
1400 IS_TUPLE,
1401 self.set.to_latex_string()
1402 )
1403 }
1404}
1405
1406impl NotLessEqualFact {
1407 pub fn to_latex_string(&self) -> String {
1408 format!(
1409 r"{} \nleq {}",
1410 self.left.to_latex_string(),
1411 self.right.to_latex_string()
1412 )
1413 }
1414}
1415
1416impl NotLessFact {
1417 pub fn to_latex_string(&self) -> String {
1418 format!(
1419 r"{} \nless {}",
1420 self.left.to_latex_string(),
1421 self.right.to_latex_string()
1422 )
1423 }
1424}
1425
1426impl NotNormalAtomicFact {
1427 pub fn to_latex_string(&self) -> String {
1428 let pred = self.predicate.to_latex_string();
1429 let args = self
1430 .body
1431 .iter()
1432 .map(|o| o.to_latex_string())
1433 .collect::<Vec<_>>()
1434 .join(", ");
1435 format!(r"\neg \left( \$ {}\left( {}\right) \right)", pred, args)
1436 }
1437}
1438
1439impl NotRestrictFact {
1440 pub fn to_latex_string(&self) -> String {
1441 format!(
1442 r"\neg \left( {} \mathrel{{\$}} \mathrm{{{}}}\, {} \right)",
1443 self.obj.to_latex_string(),
1444 RESTRICT_FN_IN,
1445 self.obj_cannot_restrict_to_fn_set.to_latex_string()
1446 )
1447 }
1448}
1449
1450impl NotSubsetFact {
1451 pub fn to_latex_string(&self) -> String {
1452 format!(
1453 r"\neg \left( {} \subseteq {} \right)",
1454 self.left.to_latex_string(),
1455 self.right.to_latex_string()
1456 )
1457 }
1458}
1459
1460impl NotSupersetFact {
1461 pub fn to_latex_string(&self) -> String {
1462 format!(
1463 r"\neg \left( {} \supseteq {} \right)",
1464 self.left.to_latex_string(),
1465 self.right.to_latex_string()
1466 )
1467 }
1468}
1469
1470impl Number {
1471 pub fn to_latex_string(&self) -> String {
1472 self.normalized_value.clone()
1473 }
1474}
1475
1476impl ObjAtIndex {
1477 pub fn to_latex_string(&self) -> String {
1478 format!(
1479 r"{}\left[ {} \right]",
1480 self.obj.to_latex_string(),
1481 self.index.to_latex_string()
1482 )
1483 }
1484}
1485
1486impl OrFact {
1487 pub fn to_latex_string(&self) -> String {
1488 self.facts
1489 .iter()
1490 .map(|f| f.to_latex_string())
1491 .collect::<Vec<_>>()
1492 .join(r" \lor ")
1493 }
1494}
1495
1496impl ParamDefWithType {
1497 pub fn to_latex_string(&self) -> String {
1498 self.groups
1499 .iter()
1500 .map(|g| g.to_latex_string())
1501 .collect::<Vec<_>>()
1502 .join(", ")
1503 }
1504}
1505
1506impl ParamGroupWithParamType {
1507 pub fn to_latex_string(&self) -> String {
1508 let names = self
1509 .params
1510 .iter()
1511 .map(|p| latex_local_ident(p))
1512 .collect::<Vec<_>>()
1513 .join(", ");
1514 format!(r"{}, {}", names, self.param_type.to_latex_string())
1515 }
1516}
1517
1518impl ParamType {
1519 pub fn to_latex_string(&self) -> String {
1520 match self {
1521 ParamType::Set(_) => format!(r"\mathrm{{{}}}", SET),
1522 ParamType::NonemptySet(_) => format!(r"\mathrm{{{}}}", NONEMPTY_SET),
1523 ParamType::FiniteSet(_) => format!(r"\mathrm{{{}}}", FINITE_SET),
1524 ParamType::Restrictive(fs) => format!(
1525 r"\mathrm{{{}}} {}{}{}",
1526 RESTRICTIVE,
1527 "(",
1528 Obj::FnSet(fs.clone()).to_latex_string(),
1529 ")"
1530 ),
1531 ParamType::Obj(o) => o.to_latex_string(),
1532 }
1533 }
1534}
1535
1536impl Pow {
1537 pub fn to_latex_string(&self) -> String {
1538 format!(
1539 "{{{}}}^{{{}}}",
1540 self.base.to_latex_string(),
1541 self.exponent.to_latex_string()
1542 )
1543 }
1544}
1545
1546impl PowerSet {
1547 pub fn to_latex_string(&self) -> String {
1548 format!(r"\mathcal{{P}}\left( {}\right)", self.set.to_latex_string())
1549 }
1550}
1551
1552impl Proj {
1553 pub fn to_latex_string(&self) -> String {
1554 format!(
1555 r"\operatorname{{{}}}\left( {}, {} \right)",
1556 PROJ,
1557 self.set.to_latex_string(),
1558 self.dim.to_latex_string()
1559 )
1560 }
1561}
1562
1563impl ProveStmt {
1564 pub fn to_latex_string(&self) -> String {
1565 if self.proof.is_empty() {
1566 return r"\text{\texttt{(empty proof)}}".to_string();
1567 }
1568 let rows: Vec<String> = self
1569 .proof
1570 .iter()
1571 .map(|st| format!(r"& \quad {}", st.to_latex_string()))
1572 .collect();
1573 format!(
1574 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
1575 rows.join(" \\\\\n")
1576 )
1577 }
1578}
1579
1580impl Range {
1581 pub fn to_latex_string(&self) -> String {
1582 format!(
1583 r"\operatorname{{{}}}\left( {}, {} \right)",
1584 RANGE,
1585 self.start.to_latex_string(),
1586 self.end.to_latex_string()
1587 )
1588 }
1589}
1590
1591impl RestrictFact {
1592 pub fn to_latex_string(&self) -> String {
1593 format!(
1594 r"{} \mathrel{{\$}} \mathrm{{{}}}\, {}",
1595 self.obj.to_latex_string(),
1596 RESTRICT_FN_IN,
1597 self.obj_can_restrict_to_fn_set.to_latex_string()
1598 )
1599 }
1600}
1601
1602impl RunFileStmt {
1603 pub fn to_latex_string(&self) -> String {
1604 format!(
1605 r"\operatorname{{{}}}\ \texttt{{{}}}",
1606 RUN_FILE,
1607 latex_texttt_escape(&self.file_path)
1608 )
1609 }
1610}
1611
1612impl SeqSet {
1613 pub fn to_latex_string(&self) -> String {
1614 format!(
1615 r"\operatorname{{{}}}\left( {}\right)",
1616 SEQ,
1617 self.set.to_latex_string()
1618 )
1619 }
1620}
1621
1622impl SetBuilder {
1623 pub fn to_latex_string(&self) -> String {
1624 let cond = self
1625 .facts
1626 .iter()
1627 .map(|f| f.to_latex_string())
1628 .collect::<Vec<_>>()
1629 .join(r" \land ");
1630 format!(
1631 r"\left\{{ {} \in {} \,\middle|\, {} \right\}}",
1632 latex_local_ident(&self.param),
1633 self.param_set.to_latex_string(),
1634 cond
1635 )
1636 }
1637}
1638
1639impl SetDiff {
1640 pub fn to_latex_string(&self) -> String {
1641 format!(
1642 r"\operatorname{{{}}}\left( {}, {} \right)",
1643 SET_DIFF,
1644 self.left.to_latex_string(),
1645 self.right.to_latex_string()
1646 )
1647 }
1648}
1649
1650impl SetMinus {
1651 pub fn to_latex_string(&self) -> String {
1652 format!(
1653 r"{} \setminus {}",
1654 self.left.to_latex_string(),
1655 self.right.to_latex_string()
1656 )
1657 }
1658}
1659
1660impl Sub {
1661 pub fn to_latex_string(&self) -> String {
1662 format!(
1663 "{} - {}",
1664 self.left.to_latex_string(),
1665 self.right.to_latex_string()
1666 )
1667 }
1668}
1669
1670impl SubsetFact {
1671 pub fn to_latex_string(&self) -> String {
1672 format!(
1673 r"{} \subseteq {}",
1674 self.left.to_latex_string(),
1675 self.right.to_latex_string()
1676 )
1677 }
1678}
1679
1680impl SupersetFact {
1681 pub fn to_latex_string(&self) -> String {
1682 format!(
1683 r"{} \supseteq {}",
1684 self.left.to_latex_string(),
1685 self.right.to_latex_string()
1686 )
1687 }
1688}
1689
1690impl Tuple {
1691 pub fn to_latex_string(&self) -> String {
1692 let inner = self
1693 .args
1694 .iter()
1695 .map(|o| o.to_latex_string())
1696 .collect::<Vec<_>>()
1697 .join(", ");
1698 format!(r"\left( {} \right)", inner)
1699 }
1700}
1701
1702impl TupleDim {
1703 pub fn to_latex_string(&self) -> String {
1704 format!(
1705 r"\operatorname{{{}}}\left( {}\right)",
1706 TUPLE_DIM,
1707 self.arg.to_latex_string()
1708 )
1709 }
1710}
1711
1712impl Union {
1713 pub fn to_latex_string(&self) -> String {
1714 format!(
1715 r"{} \cup {}",
1716 self.left.to_latex_string(),
1717 self.right.to_latex_string()
1718 )
1719 }
1720}
1721
1722impl WitnessExistFact {
1723 pub fn to_latex_string(&self) -> String {
1724 let names = self
1725 .equal_tos
1726 .iter()
1727 .map(|o| o.to_latex_string())
1728 .collect::<Vec<_>>()
1729 .join(", ");
1730 let facts = self
1731 .exist_fact_in_witness
1732 .facts()
1733 .iter()
1734 .map(|f| f.to_latex_string())
1735 .collect::<Vec<_>>()
1736 .join(", ");
1737 let head = format!(
1738 r"\mathrm{{witness}}\ {} : {} \mathrm{{st}} \left\{{ {}\right\}}",
1739 names,
1740 self.exist_fact_in_witness
1741 .params_def_with_type()
1742 .to_latex_string(),
1743 facts
1744 );
1745 if self.proof.is_empty() {
1746 head
1747 } else {
1748 let mut rows = vec![format!(r"{} &", head)];
1749 for st in &self.proof {
1750 rows.push(format!(r"& \quad {}", st.to_latex_string()));
1751 }
1752 format!(
1753 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
1754 rows.join(" \\\\\n")
1755 )
1756 }
1757 }
1758}
1759
1760impl WitnessNonemptySet {
1761 pub fn to_latex_string(&self) -> String {
1762 let head = format!(
1763 r"\mathrm{{witness}}\ {} {}",
1764 self.obj.to_latex_string(),
1765 self.set.to_latex_string()
1766 );
1767 if self.proof.is_empty() {
1768 head
1769 } else {
1770 let mut rows = vec![format!(r"{} &", head)];
1771 for st in &self.proof {
1772 rows.push(format!(r"& \quad {}", st.to_latex_string()));
1773 }
1774 format!(
1775 "\\begin{{aligned}}\n{}\n\\end{{aligned}}",
1776 rows.join(" \\\\\n")
1777 )
1778 }
1779 }
1780}
1781
1782impl ImportGlobalModuleStmt {
1783 pub fn to_latex_string(&self) -> String {
1784 match &self.as_mod_name {
1785 Some(m) => format!(
1786 r"\operatorname{{{}}}\ {}\ \mathrm{{as}}\ {}",
1787 IMPORT,
1788 latex_local_ident(&self.mod_name),
1789 latex_local_ident(m)
1790 ),
1791 None => format!(
1792 r"\operatorname{{{}}}\ {}",
1793 IMPORT,
1794 latex_local_ident(&self.mod_name)
1795 ),
1796 }
1797 }
1798}
1799
1800impl ImportRelativePathStmt {
1801 pub fn to_latex_string(&self) -> String {
1802 let path = latex_texttt_escape(&self.path);
1803 match &self.as_mod_name {
1804 Some(m) => format!(
1805 r"\operatorname{{{}}}\ \texttt{{{}}}\ \mathrm{{as}}\ {}",
1806 IMPORT,
1807 path,
1808 latex_local_ident(m)
1809 ),
1810 None => format!(r"\operatorname{{{}}}\ \texttt{{{}}}", IMPORT, path),
1811 }
1812 }
1813}
1814
1815impl ImportStmt {
1816 pub fn to_latex_string(&self) -> String {
1817 match self {
1818 ImportStmt::ImportRelativePath(s) => s.to_latex_string(),
1819 ImportStmt::ImportGlobalModule(s) => s.to_latex_string(),
1820 }
1821 }
1822}
1823
1824impl StandardSet {
1825 pub fn to_latex_string(&self) -> String {
1826 match self {
1827 StandardSet::N => r"\mathbb{N}".to_string(),
1828 StandardSet::NPos => r"\mathbb{N}_{>0}".to_string(),
1829 StandardSet::Z => r"\mathbb{Z}".to_string(),
1830 StandardSet::ZNeg => r"\mathbb{Z}_{<0}".to_string(),
1831 StandardSet::ZNz => r"\mathbb{Z}\setminus\{0\}".to_string(),
1832 StandardSet::Q => r"\mathbb{Q}".to_string(),
1833 StandardSet::QPos => r"\mathbb{Q}_{>0}".to_string(),
1834 StandardSet::QNeg => r"\mathbb{Q}_{<0}".to_string(),
1835 StandardSet::QNz => r"\mathbb{Q}\setminus\{0\}".to_string(),
1836 StandardSet::R => r"\mathbb{R}".to_string(),
1837 StandardSet::RPos => r"\mathbb{R}_{>0}".to_string(),
1838 StandardSet::RNeg => r"\mathbb{R}_{<0}".to_string(),
1839 StandardSet::RNz => r"\mathbb{R}\setminus\{0\}".to_string(),
1840 }
1841 }
1842}
1843
1844impl Fact {
1845 pub fn to_latex_string(&self) -> String {
1846 match self {
1847 Fact::AtomicFact(x) => x.to_latex_string(),
1848 Fact::ExistFact(x) => x.to_latex_string(),
1849 Fact::OrFact(x) => x.to_latex_string(),
1850 Fact::AndFact(x) => x.to_latex_string(),
1851 Fact::ChainFact(x) => x.to_latex_string(),
1852 Fact::ForallFact(x) => x.to_latex_string(),
1853 Fact::ForallFactWithIff(x) => x.to_latex_string(),
1854 }
1855 }
1856}
1857
1858impl AtomicFact {
1859 pub fn to_latex_string(&self) -> String {
1860 match self {
1861 AtomicFact::NormalAtomicFact(x) => x.to_latex_string(),
1862 AtomicFact::EqualFact(x) => x.to_latex_string(),
1863 AtomicFact::LessFact(x) => x.to_latex_string(),
1864 AtomicFact::GreaterFact(x) => x.to_latex_string(),
1865 AtomicFact::LessEqualFact(x) => x.to_latex_string(),
1866 AtomicFact::GreaterEqualFact(x) => x.to_latex_string(),
1867 AtomicFact::IsSetFact(x) => x.to_latex_string(),
1868 AtomicFact::IsNonemptySetFact(x) => x.to_latex_string(),
1869 AtomicFact::IsFiniteSetFact(x) => x.to_latex_string(),
1870 AtomicFact::InFact(x) => x.to_latex_string(),
1871 AtomicFact::IsCartFact(x) => x.to_latex_string(),
1872 AtomicFact::IsTupleFact(x) => x.to_latex_string(),
1873 AtomicFact::SubsetFact(x) => x.to_latex_string(),
1874 AtomicFact::SupersetFact(x) => x.to_latex_string(),
1875 AtomicFact::RestrictFact(x) => x.to_latex_string(),
1876 AtomicFact::NotRestrictFact(x) => x.to_latex_string(),
1877 AtomicFact::NotNormalAtomicFact(x) => x.to_latex_string(),
1878 AtomicFact::NotEqualFact(x) => x.to_latex_string(),
1879 AtomicFact::NotLessFact(x) => x.to_latex_string(),
1880 AtomicFact::NotGreaterFact(x) => x.to_latex_string(),
1881 AtomicFact::NotLessEqualFact(x) => x.to_latex_string(),
1882 AtomicFact::NotGreaterEqualFact(x) => x.to_latex_string(),
1883 AtomicFact::NotIsSetFact(x) => x.to_latex_string(),
1884 AtomicFact::NotIsNonemptySetFact(x) => x.to_latex_string(),
1885 AtomicFact::NotIsFiniteSetFact(x) => x.to_latex_string(),
1886 AtomicFact::NotInFact(x) => x.to_latex_string(),
1887 AtomicFact::NotIsCartFact(x) => x.to_latex_string(),
1888 AtomicFact::NotIsTupleFact(x) => x.to_latex_string(),
1889 AtomicFact::NotSubsetFact(x) => x.to_latex_string(),
1890 AtomicFact::NotSupersetFact(x) => x.to_latex_string(),
1891 AtomicFact::FnEqualInFact(f) => format!(
1892 r"\mathsf{{fn\_eq\_in}}({},{},{})",
1893 f.left.to_latex_string(),
1894 f.right.to_latex_string(),
1895 f.set.to_latex_string(),
1896 ),
1897 AtomicFact::FnEqualFact(f) => format!(
1898 r"\mathsf{{fn\_eq}}({},{})",
1899 f.left.to_latex_string(),
1900 f.right.to_latex_string(),
1901 ),
1902 }
1903 }
1904}
1905
1906impl Obj {
1907 pub fn to_latex_string(&self) -> String {
1908 match self {
1909 Obj::Atom(AtomObj::Identifier(x)) => x.to_latex_string(),
1910 Obj::Atom(AtomObj::IdentifierWithMod(x)) => x.to_latex_string(),
1911 Obj::FnObj(x) => x.to_latex_string(),
1912 Obj::Number(x) => x.to_latex_string(),
1913 Obj::Add(x) => x.to_latex_string(),
1914 Obj::Sub(x) => x.to_latex_string(),
1915 Obj::Mul(x) => x.to_latex_string(),
1916 Obj::Div(x) => x.to_latex_string(),
1917 Obj::Mod(x) => x.to_latex_string(),
1918 Obj::Pow(x) => x.to_latex_string(),
1919 Obj::Abs(x) => x.to_latex_string(),
1920 Obj::Log(x) => x.to_latex_string(),
1921 Obj::Max(x) => x.to_latex_string(),
1922 Obj::Min(x) => x.to_latex_string(),
1923 Obj::Union(x) => x.to_latex_string(),
1924 Obj::Intersect(x) => x.to_latex_string(),
1925 Obj::SetMinus(x) => x.to_latex_string(),
1926 Obj::SetDiff(x) => x.to_latex_string(),
1927 Obj::Cup(x) => x.to_latex_string(),
1928 Obj::Cap(x) => x.to_latex_string(),
1929 Obj::PowerSet(x) => x.to_latex_string(),
1930 Obj::ListSet(x) => x.to_latex_string(),
1931 Obj::SetBuilder(x) => x.to_latex_string(),
1932 Obj::FnSet(x) => x.to_latex_string(),
1933 Obj::AnonymousFn(x) => x.to_latex_string(),
1934 Obj::Cart(x) => x.to_latex_string(),
1935 Obj::CartDim(x) => x.to_latex_string(),
1936 Obj::Proj(x) => x.to_latex_string(),
1937 Obj::TupleDim(x) => x.to_latex_string(),
1938 Obj::Tuple(x) => x.to_latex_string(),
1939 Obj::Count(x) => x.to_latex_string(),
1940 Obj::Sum(x) => x.to_latex_string(),
1941 Obj::Product(x) => x.to_latex_string(),
1942 Obj::Range(x) => x.to_latex_string(),
1943 Obj::ClosedRange(x) => x.to_latex_string(),
1944 Obj::FiniteSeqSet(x) => x.to_latex_string(),
1945 Obj::SeqSet(x) => x.to_latex_string(),
1946 Obj::FiniteSeqListObj(x) => x.to_latex_string(),
1947 Obj::Choose(x) => x.to_latex_string(),
1948 Obj::ObjAtIndex(x) => x.to_latex_string(),
1949 Obj::StandardSet(x) => x.to_latex_string(),
1950 Obj::FamilyObj(x) => x.to_latex_string(),
1951 Obj::Atom(AtomObj::Forall(x)) => latex_local_ident(&x.name),
1952 Obj::Atom(AtomObj::Def(x)) => latex_local_ident(&x.name),
1953 Obj::Atom(AtomObj::Exist(x)) => latex_local_ident(&x.name),
1954 Obj::Atom(AtomObj::SetBuilder(x)) => latex_local_ident(&x.name),
1955 Obj::Atom(AtomObj::FnSet(x)) => latex_local_ident(&x.name),
1956 Obj::Atom(AtomObj::Induc(x)) => latex_local_ident(&x.name),
1957 Obj::Atom(AtomObj::DefAlgo(x)) => latex_local_ident(&x.name),
1958 Obj::MatrixSet(x) => x.to_latex_string(),
1959 Obj::MatrixListObj(x) => x.to_latex_string(),
1960 Obj::MatrixAdd(x) => x.to_latex_string(),
1961 Obj::MatrixSub(x) => x.to_latex_string(),
1962 Obj::MatrixMul(x) => x.to_latex_string(),
1963 Obj::MatrixScalarMul(x) => x.to_latex_string(),
1964 Obj::MatrixPow(x) => x.to_latex_string(),
1965 }
1966 }
1967}
1968
1969impl Stmt {
1970 pub fn to_latex_string(&self) -> String {
1971 match self {
1972 Stmt::Fact(x) => x.to_latex_string(),
1973 Stmt::DefLetStmt(x) => x.to_latex_string(),
1974 Stmt::DefPropStmt(x) => x.to_latex_string(),
1975 Stmt::DefAbstractPropStmt(x) => x.to_latex_string(),
1976 Stmt::HaveObjInNonemptySetStmt(x) => x.to_latex_string(),
1977 Stmt::HaveObjEqualStmt(x) => x.to_latex_string(),
1978 Stmt::HaveByExistStmt(x) => x.to_latex_string(),
1979 Stmt::HaveFnEqualStmt(x) => x.to_latex_string(),
1980 Stmt::HaveFnEqualCaseByCaseStmt(x) => x.to_latex_string(),
1981 Stmt::HaveFnByInducStmt(x) => x.to_latex_string(),
1982 Stmt::DefFamilyStmt(x) => x.to_latex_string(),
1983 Stmt::DefAlgoStmt(x) => x.to_latex_string(),
1984 Stmt::ClaimStmt(x) => x.to_latex_string(),
1985 Stmt::KnowStmt(x) => x.to_latex_string(),
1986 Stmt::ProveStmt(x) => x.to_latex_string(),
1987 Stmt::ImportStmt(x) => x.to_latex_string(),
1988 Stmt::DoNothingStmt(x) => x.to_latex_string(),
1989 Stmt::ClearStmt(x) => x.to_latex_string(),
1990 Stmt::RunFileStmt(x) => x.to_latex_string(),
1991 Stmt::EvalStmt(x) => x.to_latex_string(),
1992 Stmt::WitnessExistFact(x) => x.to_latex_string(),
1993 Stmt::WitnessNonemptySet(x) => x.to_latex_string(),
1994 Stmt::ByCasesStmt(x) => x.to_latex_string(),
1995 Stmt::ByContraStmt(x) => x.to_latex_string(),
1996 Stmt::ByEnumerateFiniteSetStmt(x) => x.to_latex_string(),
1997 Stmt::ByInducStmt(x) => x.to_latex_string(),
1998 Stmt::ByForStmt(x) => x.to_latex_string(),
1999 Stmt::ByExtensionStmt(x) => x.to_latex_string(),
2000 Stmt::ByFnStmt(x) => x.to_latex_string(),
2001 Stmt::ByFamilyStmt(x) => x.to_latex_string(),
2002 Stmt::ByTuple(x) => x.to_latex_string(),
2003 Stmt::ByFnSetStmt(x) => x.to_latex_string(),
2004 Stmt::ByFiniteSeqSetStmt(x) => x.to_latex_string(),
2005 Stmt::BySeqSetStmt(x) => x.to_latex_string(),
2006 Stmt::ByMatrixSetStmt(x) => x.to_latex_string(),
2007 Stmt::ByEnumerateClosedRangeStmt(x) => x.to_latex_string(),
2008 }
2009 }
2010}