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