1use std::fmt;
4
5use crate::dbl::model::DiscreteDblModel;
6use crate::dbl::model::MutDblModel;
7use crate::dbl::model::{DblModel, FgDblModel};
8use crate::one::category::FgCategory;
9use crate::tt::stx::MorphismType;
10use crate::tt::{eval::*, prelude::*, toplevel::*, val::*};
11use crate::zero::QualifiedLabel;
12use crate::zero::QualifiedName;
13
14pub fn generate(
18 toplevel: &Toplevel,
19 theory: &Theory,
20 ty: &TyV,
21) -> (DiscreteDblModel, HashMap<QualifiedName, QualifiedLabel>) {
22 let eval = Evaluator::new(toplevel, Env::Nil, 0);
23 let (elt, eval) = eval.bind_self(ty.clone());
24 let elt = eval.eta_neu(&elt, ty);
25 let mut out = DiscreteDblModel::new(theory.definition.clone());
26 let mut name_translation = HashMap::new();
27 extract_to(&eval, &mut out, &mut name_translation, vec![], vec![], &elt, ty);
28 (out, name_translation)
29}
30
31fn name_of(val: &TmV) -> QualifiedName {
33 let mut out = Vec::new();
34 let mut n = val.as_neu();
35 while let TmN_::Proj(n1, f, _) = &*n.clone() {
36 n = n1.clone();
37 out.push(*f);
38 }
39 out.reverse();
40 out.into()
41}
42
43fn extract_to(
44 eval: &Evaluator,
45 out: &mut DiscreteDblModel,
46 name_translation: &mut HashMap<QualifiedName, QualifiedLabel>,
47 prefix: Vec<NameSegment>,
48 label_prefix: Vec<LabelSegment>,
49 val: &TmV,
50 ty: &TyV,
51) {
52 match &**ty {
53 TyV_::Object(ot) => {
54 out.add_ob(prefix.clone().into(), ot.clone());
55 name_translation.insert(prefix.into(), label_prefix.into());
56 }
57 TyV_::Morphism(mt, dom, cod) => {
58 out.add_mor(prefix.clone().into(), name_of(dom), name_of(cod), mt.0.clone());
59 name_translation.insert(prefix.into(), label_prefix.into());
60 }
61 TyV_::Record(r) => {
62 for (name, (label, _)) in r.fields1.iter() {
63 let mut prefix = prefix.clone();
64 prefix.push(*name);
65 let mut label_prefix = label_prefix.clone();
66 label_prefix.push(*label);
67 extract_to(
68 eval,
69 out,
70 name_translation,
71 prefix,
72 label_prefix,
73 &eval.proj(val, *name, *label),
74 &eval.field_ty(ty, val, *name),
75 )
76 }
77 }
78 TyV_::Sing(_, _) => {}
79 TyV_::Unit => {}
80 }
81}
82
83pub fn model_output(
85 prefix: &str,
86 out: &mut impl fmt::Write,
87 model: &DiscreteDblModel,
88 name_translation: &HashMap<QualifiedName, QualifiedLabel>,
89) -> fmt::Result {
90 writeln!(out, "{prefix}object generators:")?;
91 for obgen in model.ob_generators() {
92 writeln!(
93 out,
94 "{prefix} {} : {}",
95 name_translation.get(&obgen).unwrap(),
96 model.ob_type(&obgen)
97 )?;
98 }
99 writeln!(out, "{prefix}morphism generators:")?;
100 for morgen in model.mor_generators() {
101 writeln!(
102 out,
103 "{prefix} {} : {} -> {} ({})",
104 name_translation.get(&morgen).unwrap(),
105 name_translation.get(&model.mor_generator_dom(&morgen)).unwrap(),
106 name_translation.get(&model.mor_generator_cod(&morgen)).unwrap(),
107 MorphismType(model.mor_generator_type(&morgen))
108 )?;
109 }
110 Ok(())
111}