1use crate::*;
26
27use formally::{
28 io::print::{Pretty, RcDoc},
29 smt::smtlib::ast,
30 support::*,
31};
32
33use formally_io::print::Print;
34use std::fmt::{Display, Formatter};
35
36impl From<Identifier<'_>> for ast::Symbol {
37 fn from(value: Identifier<'_>) -> Self {
38 ast::Symbol::Quoted(ast::QuotedSymbol {
39 span: value.span().clone(),
40 value: value.into_string(),
41 })
42 .simplify()
43 }
44}
45
46impl From<Identifier<'_>> for ast::QualifiedIdentifier {
47 fn from(value: Identifier<'_>) -> Self {
48 let symbol = ast::Symbol::from(value);
49 ast::QualifiedIdentifier {
50 span: symbol.span(),
51 id: ast::Identifier::Symbol(symbol),
52 sort: None,
53 }
54 }
55}
56
57impl From<Constant> for ast::Constant {
58 fn from(cnst: Constant) -> Self {
59 match cnst {
60 Constant::Integer { value, span } => ast::Constant::Numeral(ast::Numeral {
61 value: (*value).clone(),
62 span,
63 }),
64 Constant::Rational { value, span } => ast::Constant::Decimal(ast::Decimal {
65 value: (*value).clone(),
66 span,
67 }),
68 }
69 }
70}
71
72impl From<Term> for ast::Term {
73 fn from(term: Term) -> Self {
74 match term.kind() {
75 TermKind::Constant(cnst) => ast::Term::Constant(ast::Constant::from(cnst.clone())),
76 TermKind::Atom(atom) => {
77 let (id, arguments) = match &atom.head {
78 FunctionRef::Bound(BoundRef { function, .. }) => {
79 (function.name().clone(), &*atom.arguments)
80 }
81 FunctionRef::Unbound(name) => {
82 (name.clone(), &*atom.arguments)
83 }
84 };
85
86 ast::Term::Application(ast::Application {
87 head: ast::QualifiedIdentifier::from(id),
88 args: arguments
89 .iter()
90 .map(|arg| ast::Term::from(arg.clone()))
91 .collect(),
92 span: None,
93 })
94 }
95 TermKind::Quantified(quant) => match quant.quantifier {
96 Quantifier::Forall => ast::Term::Forall(ast::Forall {
97 bindings: quant
98 .variables
99 .iter()
100 .map(|var| ast::SortedVar::from(var.clone()))
101 .collect(),
102 body: Box::new(ast::Term::from(quant.body.clone())),
103 span: quant.span.clone(),
104 }),
105 Quantifier::Exists => ast::Term::Exists(ast::Exists {
106 bindings: quant
107 .variables
108 .iter()
109 .map(|var| ast::SortedVar::from(var.clone()))
110 .collect(),
111 body: Box::new(ast::Term::from(quant.body.clone())),
112 span: quant.span.clone(),
113 }),
114 },
115 TermKind::Let(let_) => ast::Term::Let(ast::Let {
116 bindings: let_
117 .bindings
118 .iter()
119 .map(|bind| ast::Binding::from(bind.clone()))
120 .collect(),
121 body: Box::new(ast::Term::from(let_.body.clone())),
122 span: let_.span.clone(),
123 }),
124 }
125 }
126}
127
128impl From<Variable> for ast::SortedVar {
129 fn from(var: Variable) -> Self {
130 ast::SortedVar {
131 name: ast::Symbol::from(var.name().clone()),
132 sort: ast::Sort::from(var.sort().clone()),
133 span: var.span().clone(),
134 }
135 }
136}
137
138impl From<Binding> for ast::Binding {
139 fn from(bind: Binding) -> Self {
140 ast::Binding {
141 name: ast::Symbol::from(bind.variable.name().clone()),
142 body: ast::Term::from(bind.def.clone()),
143 span: bind.span.clone(),
144 }
145 }
146}
147
148impl From<Sort> for ast::Sort {
149 fn from(value: Sort) -> Self {
150 let head = ast::Identifier::Symbol(ast::Symbol::from(value.head.name().clone()));
151
152 if value.arguments.is_empty() {
153 ast::Sort::Simple(head)
154 } else {
155 let mut args = Vec::new();
156 for arg in &*value.arguments {
157 match arg {
158 SortArgument::Value(_) => todo!(),
159 SortArgument::Sort(arg) => args.push(ast::Sort::from(arg.clone())),
160 }
161 }
162 ast::Sort::Application(ast::SortApplication {
163 head,
164 args,
165 span: None,
166 })
167 }
168 }
169}
170
171impl Pretty for Term {
172 fn pretty(&self) -> RcDoc<'static> {
173 ast::Term::from(self.clone()).pretty()
174 }
175}
176
177impl Display for Term {
178 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
179 self.render_fmt(f, u16::MAX)
180 }
181}
182
183impl Pretty for Sort {
184 fn pretty(&self) -> RcDoc<'static> {
185 ast::Sort::from(self.clone()).pretty()
186 }
187}
188
189impl Display for Sort {
190 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
191 self.render_fmt(f, u16::MAX)
192 }
193}