1use super::noun::NounParsing;
16use super::quantifier::QuantifierParsing;
17use super::{ParseResult, Parser};
18use crate::ast::{LogicExpr, NounPhrase, NumberKind, QuantifierKind, TemporalOperator, Term};
19use crate::error::{ParseError, ParseErrorKind};
20use crate::lexicon::{self, Time};
21use crate::token::{MeasureKind, PresupKind, TokenType};
22
23pub trait PragmaticsParsing<'a, 'ctx, 'int> {
34 fn parse_focus(&mut self) -> ParseResult<&'a LogicExpr<'a>>;
43
44 fn parse_measure(&mut self) -> ParseResult<&'a LogicExpr<'a>>;
50
51 fn parse_presupposition(
63 &mut self,
64 subject: &NounPhrase<'a>,
65 presup_kind: PresupKind,
66 ) -> ParseResult<&'a LogicExpr<'a>>;
67
68 fn parse_predicate_for_subject(&mut self, subject: &NounPhrase<'a>)
74 -> ParseResult<&'a LogicExpr<'a>>;
75
76 fn parse_scopal_adverb(&mut self, subject: &NounPhrase<'a>) -> ParseResult<&'a LogicExpr<'a>>;
82
83 fn parse_superlative(&mut self, subject: &NounPhrase<'a>) -> ParseResult<&'a LogicExpr<'a>>;
89
90 fn parse_comparative(
99 &mut self,
100 subject: &NounPhrase<'a>,
101 copula_time: Time,
102 difference: Option<&'a Term<'a>>,
103 ) -> ParseResult<&'a LogicExpr<'a>>;
104
105 fn check_number(&self) -> bool;
110
111 fn parse_measure_phrase(&mut self) -> ParseResult<&'a Term<'a>>;
119}
120
121impl<'a, 'ctx, 'int> PragmaticsParsing<'a, 'ctx, 'int> for Parser<'a, 'ctx, 'int> {
122 fn parse_focus(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
123 let kind = if let TokenType::Focus(k) = self.advance().kind {
124 k
125 } else {
126 return Err(ParseError {
127 kind: ParseErrorKind::ExpectedFocusParticle,
128 span: self.current_span(),
129 });
130 };
131
132 if self.check_quantifier() {
133 self.advance();
134 let quantified = self.parse_quantified()?;
135 let focus_var = self.interner.intern("focus");
136 let focused = self.ctx.terms.alloc(Term::Variable(focus_var));
137 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
138 kind,
139 focused,
140 scope: quantified,
141 }));
142 }
143
144 let focused_np = self.parse_noun_phrase(true)?;
145 let focused = self.ctx.terms.alloc(Term::Constant(focused_np.noun));
146
147 let scope = self.parse_predicate_for_subject(&focused_np)?;
148
149 Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
150 kind,
151 focused,
152 scope,
153 }))
154 }
155
156 fn parse_measure(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
157 let kind = if let TokenType::Measure(k) = self.advance().kind {
158 k
159 } else {
160 return Err(ParseError {
161 kind: ParseErrorKind::UnexpectedToken {
162 expected: TokenType::Measure(MeasureKind::Much),
163 found: self.peek().kind.clone(),
164 },
165 span: self.current_span(),
166 });
167 };
168
169 let np = self.parse_noun_phrase(true)?;
170 let var = self.next_var_name();
171
172 let noun_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
173 name: np.noun,
174 args: self.ctx.terms.alloc_slice([Term::Variable(var)]),
175 world: None,
176 });
177
178 let measure_sym = self.interner.intern("Measure");
179 let kind_sym = self.interner.intern(match kind {
180 MeasureKind::Much => "Much",
181 MeasureKind::Little => "Little",
182 });
183 let measure_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
184 name: measure_sym,
185 args: self
186 .ctx
187 .terms
188 .alloc_slice([Term::Variable(var), Term::Constant(kind_sym)]),
189 world: None,
190 });
191
192 let (pred_expr, verb_time) = if self.check(&TokenType::Is) {
193 let copula_time = if let TokenType::Is = self.advance().kind {
194 Time::Present
195 } else {
196 Time::Present
197 };
198
199 if self.check_comparative() {
201 let subj_np = NounPhrase {
202 noun: np.noun,
203 definiteness: None,
204 adjectives: &[],
205 possessor: None,
206 pps: &[],
207 superlative: None,
208 };
209 let comp_expr = self.parse_comparative(&subj_np, copula_time, None)?;
210
211 let combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
212 left: noun_pred,
213 op: TokenType::And,
214 right: self.ctx.exprs.alloc(LogicExpr::BinaryOp {
215 left: measure_pred,
216 op: TokenType::And,
217 right: comp_expr,
218 }),
219 });
220
221 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
222 kind: QuantifierKind::Existential,
223 variable: var,
224 body: combined,
225 island_id: self.current_island,
226 }));
227 }
228
229 let adj = self.consume_content_word()?;
230 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
231 name: adj,
232 args: self.ctx.terms.alloc_slice([Term::Variable(var)]),
233 world: None,
234 });
235 (adj_pred, copula_time)
236 } else {
237 let (verb, verb_time, _, _) = self.consume_verb_with_metadata();
238 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
239 name: verb,
240 args: self.ctx.terms.alloc_slice([Term::Variable(var)]),
241 world: None,
242 });
243 (verb_pred, verb_time)
244 };
245
246 let combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
247 left: noun_pred,
248 op: TokenType::And,
249 right: self.ctx.exprs.alloc(LogicExpr::BinaryOp {
250 left: measure_pred,
251 op: TokenType::And,
252 right: pred_expr,
253 }),
254 });
255
256 let with_time = match verb_time {
257 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
258 operator: TemporalOperator::Past,
259 body: combined,
260 }),
261 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
262 operator: TemporalOperator::Future,
263 body: combined,
264 }),
265 _ => combined,
266 };
267
268 Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
269 kind: QuantifierKind::Existential,
270 variable: var,
271 body: with_time,
272 island_id: self.current_island,
273 }))
274 }
275
276 fn parse_presupposition(
277 &mut self,
278 subject: &NounPhrase<'a>,
279 presup_kind: PresupKind,
280 ) -> ParseResult<&'a LogicExpr<'a>> {
281 let subject_noun = subject.noun;
282
283 let unknown = self.interner.intern("?");
284 let complement = if self.check_verb() {
285 let verb = self.consume_verb();
286 self.ctx.exprs.alloc(LogicExpr::Predicate {
287 name: verb,
288 args: self.ctx.terms.alloc_slice([Term::Constant(subject_noun)]),
289 world: None,
290 })
291 } else {
292 self.ctx.exprs.alloc(LogicExpr::Atom(unknown))
293 };
294
295 let (assertion, presupposition) = match presup_kind {
296 PresupKind::Stop => {
297 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
298 op: TokenType::Not,
299 operand: complement,
300 });
301 let past = self.ctx.exprs.alloc(LogicExpr::Temporal {
302 operator: TemporalOperator::Past,
303 body: complement,
304 });
305 (neg, past)
306 }
307 PresupKind::Start => {
308 let past = self.ctx.exprs.alloc(LogicExpr::Temporal {
309 operator: TemporalOperator::Past,
310 body: complement,
311 });
312 let neg_past = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
313 op: TokenType::Not,
314 operand: past,
315 });
316 (complement, neg_past)
317 }
318 PresupKind::Regret => {
319 let regret_sym = self.interner.intern("Regret");
320 let regret = self.ctx.exprs.alloc(LogicExpr::Predicate {
321 name: regret_sym,
322 args: self.ctx.terms.alloc_slice([Term::Constant(subject_noun)]),
323 world: None,
324 });
325 let past = self.ctx.exprs.alloc(LogicExpr::Temporal {
326 operator: TemporalOperator::Past,
327 body: complement,
328 });
329 (regret, past)
330 }
331 PresupKind::Continue | PresupKind::Realize | PresupKind::Know => {
332 let verb_name = match presup_kind {
333 PresupKind::Continue => self.interner.intern("Continue"),
334 PresupKind::Realize => self.interner.intern("Realize"),
335 PresupKind::Know => self.interner.intern("Know"),
336 _ => unknown,
337 };
338 let main = self.ctx.exprs.alloc(LogicExpr::Predicate {
339 name: verb_name,
340 args: self.ctx.terms.alloc_slice([Term::Constant(subject_noun)]),
341 world: None,
342 });
343 (main, complement)
344 }
345 };
346
347 Ok(self.ctx.exprs.alloc(LogicExpr::Presupposition {
348 assertion,
349 presupposition,
350 }))
351 }
352
353 fn parse_predicate_for_subject(
354 &mut self,
355 subject: &NounPhrase<'a>,
356 ) -> ParseResult<&'a LogicExpr<'a>> {
357 if self.check_verb() {
358 let verb = self.consume_verb();
359
360 if self.check_focus() {
362 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
363 k
364 } else {
365 crate::token::FocusKind::Only
366 };
367
368 let object_np = self.parse_noun_phrase(false)?;
369 let object_term = Term::Constant(object_np.noun);
370
371 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
372 name: verb,
373 args: self.ctx.terms.alloc_slice([
374 Term::Constant(subject.noun),
375 object_term.clone(),
376 ]),
377 world: None,
378 });
379
380 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
381 kind: focus_kind,
382 focused: self.ctx.terms.alloc(object_term),
383 scope: predicate,
384 }));
385 }
386
387 let mut args = vec![Term::Constant(subject.noun)];
388
389 if self.check_content_word() || self.check_article() {
390 let object = self.parse_noun_phrase(false)?;
391 args.push(Term::Constant(object.noun));
392 }
393
394 Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
395 name: verb,
396 args: self.ctx.terms.alloc_slice(args),
397 world: None,
398 }))
399 } else {
400 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject.noun)))
401 }
402 }
403
404 fn parse_scopal_adverb(&mut self, subject: &NounPhrase<'a>) -> ParseResult<&'a LogicExpr<'a>> {
405 let operator = if let TokenType::ScopalAdverb(adv) = self.advance().kind.clone() {
406 adv
407 } else {
408 return Err(ParseError {
409 kind: ParseErrorKind::ExpectedScopalAdverb,
410 span: self.current_span(),
411 });
412 };
413
414 if !self.check_verb() {
415 return Err(ParseError {
416 kind: ParseErrorKind::ExpectedVerb {
417 found: self.peek().kind.clone(),
418 },
419 span: self.current_span(),
420 });
421 }
422
423 let (verb, verb_time, _verb_aspect, _) = self.consume_verb_with_metadata();
424
425 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
426 name: verb,
427 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
428 world: None,
429 });
430
431 let with_time = match verb_time {
432 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
433 operator: TemporalOperator::Past,
434 body: predicate,
435 }),
436 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
437 operator: TemporalOperator::Future,
438 body: predicate,
439 }),
440 _ => predicate,
441 };
442
443 Ok(self.ctx.exprs.alloc(LogicExpr::Scopal {
444 operator,
445 body: with_time,
446 }))
447 }
448
449 fn parse_superlative(&mut self, subject: &NounPhrase<'a>) -> ParseResult<&'a LogicExpr<'a>> {
450 let adj = if let TokenType::Superlative(adj) = self.advance().kind.clone() {
451 adj
452 } else {
453 return Err(ParseError {
454 kind: ParseErrorKind::ExpectedSuperlativeAdjective,
455 span: self.current_span(),
456 });
457 };
458
459 let domain = self.consume_content_word()?;
460
461 Ok(self.ctx.exprs.alloc(LogicExpr::Superlative {
462 adjective: adj,
463 subject: self.ctx.terms.alloc(Term::Constant(subject.noun)),
464 domain,
465 }))
466 }
467
468 fn parse_comparative(
469 &mut self,
470 subject: &NounPhrase<'a>,
471 _copula_time: Time,
472 difference: Option<&'a Term<'a>>,
473 ) -> ParseResult<&'a LogicExpr<'a>> {
474 let adj = if let TokenType::Comparative(adj) = self.advance().kind.clone() {
475 adj
476 } else {
477 return Err(ParseError {
478 kind: ParseErrorKind::ExpectedComparativeAdjective,
479 span: self.current_span(),
480 });
481 };
482
483 if !self.check(&TokenType::Than) {
484 return Err(ParseError {
485 kind: ParseErrorKind::ExpectedThan,
486 span: self.current_span(),
487 });
488 }
489 self.advance();
490
491 let object_term = if self.check_number() {
493 let num_sym = if let TokenType::Number(sym) = self.advance().kind {
495 sym
496 } else {
497 unreachable!()
498 };
499 let num_str = self.interner.resolve(num_sym);
500 let num_val = num_str.parse::<i64>().unwrap_or(0);
501 self.ctx.terms.alloc(Term::Value {
502 kind: crate::ast::logic::NumberKind::Integer(num_val),
503 unit: None,
504 dimension: None,
505 })
506 } else {
507 let object = self.parse_noun_phrase(false)?;
509 let obj_term = self.ctx.terms.alloc(Term::Constant(object.noun));
510
511 let result = self.ctx.exprs.alloc(LogicExpr::Comparative {
512 adjective: adj,
513 subject: self.ctx.terms.alloc(Term::Constant(subject.noun)),
514 object: obj_term,
515 difference,
516 });
517
518 let result = self.wrap_with_definiteness(subject.definiteness, subject.noun, result)?;
519 return self.wrap_with_definiteness_for_object(object.definiteness, object.noun, result);
520 };
521
522 Ok(self.ctx.exprs.alloc(LogicExpr::Comparative {
524 adjective: adj,
525 subject: self.ctx.terms.alloc(Term::Constant(subject.noun)),
526 object: object_term,
527 difference,
528 }))
529 }
530
531 fn check_number(&self) -> bool {
532 matches!(self.peek().kind, TokenType::Number(_))
533 }
534
535 fn parse_measure_phrase(&mut self) -> ParseResult<&'a Term<'a>> {
536 let num_sym = if let TokenType::Number(sym) = self.advance().kind {
537 sym
538 } else {
539 return Err(ParseError {
540 kind: ParseErrorKind::ExpectedNumber,
541 span: self.current_span(),
542 });
543 };
544
545 let num_str = self.interner.resolve(num_sym);
546 let kind = parse_number_kind(num_str, num_sym);
547
548 let (unit, dimension) = if self.check_content_word() {
549 let unit_word = self.consume_content_word()?;
550 let unit_str = self.interner.resolve(unit_word).to_lowercase();
551 let dim = lexicon::lookup_unit_dimension(&unit_str);
552 (Some(unit_word), dim)
553 } else {
554 (None, None)
555 };
556
557 Ok(self.ctx.terms.alloc(Term::Value { kind, unit, dimension }))
558 }
559}
560
561fn parse_number_kind(s: &str, sym: crate::intern::Symbol) -> NumberKind {
562 if s.contains('.') {
563 NumberKind::Real(s.parse().unwrap_or(0.0))
564 } else if s.chars().all(|c| c.is_ascii_digit() || c == '-') {
565 NumberKind::Integer(s.parse().unwrap_or(0))
566 } else {
567 NumberKind::Symbolic(sym)
568 }
569}