1use super::clause::ClauseParsing;
25use super::modal::ModalParsing;
26use super::noun::NounParsing;
27use super::pragmatics::PragmaticsParsing;
28use super::{ParseResult, Parser};
29use crate::ast::{
30 AspectOperator, LogicExpr, NeoEventData, NounPhrase, QuantifierKind, TemporalOperator, Term,
31 ThematicRole,
32};
33use crate::drs::{Gender, Number, ReferentSource};
34use crate::error::{ParseError, ParseErrorKind};
35use logicaffeine_base::Symbol;
36use crate::lexer::Lexer;
37use crate::lexicon::{Aspect, Definiteness, Time};
38use crate::token::{FocusKind, Span, TokenType};
39
40use crate::ast::Stmt;
41
42pub trait LogicVerbParsing<'a, 'ctx, 'int> {
47 fn parse_predicate_with_subject(&mut self, subject_symbol: Symbol)
49 -> ParseResult<&'a LogicExpr<'a>>;
50 fn parse_predicate_with_subject_as_var(&mut self, subject_symbol: Symbol)
52 -> ParseResult<&'a LogicExpr<'a>>;
53 fn try_parse_plural_subject(&mut self, first_subject: &NounPhrase<'a>)
56 -> Result<Option<&'a LogicExpr<'a>>, ParseError>;
57 fn parse_control_structure(
59 &mut self,
60 subject: &NounPhrase<'a>,
61 verb: Symbol,
62 verb_time: Time,
63 ) -> ParseResult<&'a LogicExpr<'a>>;
64 fn is_control_verb(&self, verb: Symbol) -> bool;
66 fn build_group_predicate(
68 &mut self,
69 subjects: &[Symbol],
70 verb: Symbol,
71 verb_time: Time,
72 ) -> &'a LogicExpr<'a>;
73 fn build_group_transitive(
75 &mut self,
76 subjects: &[Symbol],
77 objects: &[Symbol],
78 verb: Symbol,
79 verb_time: Time,
80 ) -> &'a LogicExpr<'a>;
81}
82
83pub trait ImperativeVerbParsing<'a, 'ctx, 'int> {
87 fn parse_statement_with_subject(&mut self, subject_symbol: Symbol)
89 -> ParseResult<Stmt<'a>>;
90}
91
92impl<'a, 'ctx, 'int> Parser<'a, 'ctx, 'int> {
93 fn parse_predicate_impl(
94 &mut self,
95 subject_symbol: Symbol,
96 as_variable: bool,
97 ) -> ParseResult<&'a LogicExpr<'a>> {
98 let subject_term = if as_variable {
99 Term::Variable(subject_symbol)
100 } else {
101 Term::Constant(subject_symbol)
102 };
103
104 let subject_str = self.interner.resolve(subject_symbol).to_lowercase();
106 if subject_str == "it" && self.check_verb() {
107 if let TokenType::Verb { lemma, time, .. } = &self.peek().kind {
108 let lemma_str = self.interner.resolve(*lemma);
109 if Lexer::is_weather_verb(lemma_str) {
110 let verb = *lemma;
111 let verb_time = *time;
112 self.advance(); let event_var = self.get_event_var();
115 let suppress_existential = self.drs.in_conditional_antecedent();
116 if suppress_existential {
117 let event_class = self.interner.intern("Event");
118 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
119 }
120 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
121 event_var,
122 verb,
123 roles: self.ctx.roles.alloc_slice(vec![]), modifiers: self.ctx.syms.alloc_slice(vec![]),
125 suppress_existential,
126 world: None,
127 })));
128
129 return Ok(match verb_time {
130 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
131 operator: TemporalOperator::Past,
132 body: neo_event,
133 }),
134 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
135 operator: TemporalOperator::Future,
136 body: neo_event,
137 }),
138 _ => neo_event,
139 });
140 }
141 }
142 }
143
144 if subject_str == "it" && (self.check(&TokenType::Is) || self.check(&TokenType::Was) || self.check(&TokenType::Possessive)) {
147 let saved_pos = self.current;
148 self.advance(); if self.check_content_word() {
151 let adj_lexeme = self.peek().lexeme;
152 let adj_str = self.interner.resolve(adj_lexeme).to_lowercase();
153
154 if let Some(meta) = crate::lexicon::lookup_adjective_db(&adj_str) {
155 if meta.features.contains(&crate::lexicon::Feature::Weather) {
156 let adj_sym = self.consume_content_word().unwrap_or(adj_lexeme);
157 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
159 name: adj_sym,
160 args: self.ctx.terms.alloc_slice([]),
161 world: None,
162 }));
163 }
164 }
165 }
166 self.current = saved_pos;
168 }
169
170 if self.check(&TokenType::Never) {
171 self.advance();
172 let verb = self.consume_verb();
173 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
174 name: verb,
175 args: self.ctx.terms.alloc_slice([subject_term]),
176 world: None,
177 });
178 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
179 op: TokenType::Not,
180 operand: verb_pred,
181 }));
182 }
183
184 if self.check_modal() {
185 return self.parse_aspect_chain_with_term(subject_term.clone());
186 }
187
188 if self.check_content_word() {
189 let next_word = self.interner.resolve(self.peek().lexeme).to_lowercase();
190 if next_word == "has" || next_word == "have" || next_word == "had" {
191 let is_perfect_aspect = if self.current + 1 < self.tokens.len() {
195 let next_token = &self.tokens[self.current + 1].kind;
196 matches!(
197 next_token,
198 TokenType::Verb { .. } | TokenType::Not
199 ) && !matches!(next_token, TokenType::Number(_))
200 } else {
201 false
202 };
203 if is_perfect_aspect {
204 return self.parse_aspect_chain(subject_symbol);
205 }
206 }
208 }
209
210 if self.check(&TokenType::Had) {
211 return self.parse_aspect_chain(subject_symbol);
212 }
213
214 if self.check(&TokenType::Does) || self.check(&TokenType::Do) {
216 self.advance();
217 let is_negated = self.match_token(&[TokenType::Not]);
218
219 if self.check(&TokenType::Ever) {
220 self.advance();
221 }
222
223 if self.check_verb() {
224 let verb = self.consume_verb();
225
226 if self.check_wh_word() {
228 let wh_token = self.advance().kind.clone();
229 let is_who = matches!(wh_token, TokenType::Who);
230 let is_what = matches!(wh_token, TokenType::What);
231
232 let is_sluicing = self.is_at_end() ||
233 self.check(&TokenType::Period) ||
234 self.check(&TokenType::Comma);
235
236 if is_sluicing {
237 if let Some(template) = self.last_event_template.clone() {
238 let wh_var = self.next_var_name();
239
240 let roles: Vec<_> = if is_who {
241 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
242 .chain(template.non_agent_roles.iter().cloned())
243 .collect()
244 } else if is_what {
245 vec![
246 (ThematicRole::Agent, subject_term.clone()),
247 (ThematicRole::Theme, Term::Variable(wh_var)),
248 ]
249 } else {
250 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
251 .chain(template.non_agent_roles.iter().cloned())
252 .collect()
253 };
254
255 let event_var = self.get_event_var();
256 let suppress_existential = self.drs.in_conditional_antecedent();
257 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
258 event_var,
259 verb: template.verb,
260 roles: self.ctx.roles.alloc_slice(roles),
261 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
262 suppress_existential,
263 world: None,
264 })));
265
266 let question = self.ctx.exprs.alloc(LogicExpr::Question {
267 wh_variable: wh_var,
268 body: reconstructed,
269 });
270
271 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
272 event_var: self.get_event_var(),
273 verb,
274 roles: self.ctx.roles.alloc_slice(vec![
275 (ThematicRole::Agent, subject_term.clone()),
276 (ThematicRole::Theme, Term::Proposition(question)),
277 ]),
278 modifiers: self.ctx.syms.alloc_slice(vec![]),
279 suppress_existential,
280 world: None,
281 })));
282
283 let result = if is_negated {
284 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
285 op: TokenType::Not,
286 operand: know_event,
287 })
288 } else {
289 know_event
290 };
291
292 return Ok(result);
293 }
294 }
295 }
296
297 let roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term.clone())];
299 let modifiers: Vec<Symbol> = vec![];
300 let event_var = self.get_event_var();
301 let suppress_existential = self.drs.in_conditional_antecedent();
302
303 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
304 event_var,
305 verb,
306 roles: self.ctx.roles.alloc_slice(roles),
307 modifiers: self.ctx.syms.alloc_slice(modifiers),
308 suppress_existential,
309 world: None,
310 })));
311
312 if is_negated {
313 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
314 op: TokenType::Not,
315 operand: neo_event,
316 }));
317 }
318 return Ok(neo_event);
319 }
320 }
321
322 if self.check_auxiliary() && self.is_true_auxiliary_usage() {
326 let aux_time = if let TokenType::Auxiliary(time) = self.advance().kind {
327 time
328 } else {
329 Time::None
330 };
331 self.pending_time = Some(aux_time);
332
333 if self.match_token(&[TokenType::Not]) {
334 self.negative_depth += 1;
335
336 if self.check_verb() || self.check(&TokenType::Do) {
338 let verb = if self.check(&TokenType::Do) {
339 self.advance(); self.interner.intern("Do")
341 } else {
342 self.consume_verb()
343 };
344
345 if self.check_quantifier() {
346 let quantifier_token = self.advance().kind.clone();
347 let object_np = self.parse_noun_phrase(false)?;
348 let obj_var = self.next_var_name();
349
350 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
351 name: object_np.noun,
352 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
353 world: None,
354 });
355
356 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
357 name: verb,
358 args: self
359 .ctx
360 .terms
361 .alloc_slice([subject_term, Term::Variable(obj_var)]),
362 world: None,
363 });
364
365 let (kind, body) = match quantifier_token {
366 TokenType::Any => {
367 if self.is_negative_context() {
368 (
369 QuantifierKind::Existential,
370 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
371 left: obj_restriction,
372 op: TokenType::And,
373 right: verb_pred,
374 }),
375 )
376 } else {
377 (
378 QuantifierKind::Universal,
379 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
380 left: obj_restriction,
381 op: TokenType::Implies,
382 right: verb_pred,
383 }),
384 )
385 }
386 }
387 TokenType::Some => (
388 QuantifierKind::Existential,
389 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
390 left: obj_restriction,
391 op: TokenType::And,
392 right: verb_pred,
393 }),
394 ),
395 TokenType::All => (
396 QuantifierKind::Universal,
397 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
398 left: obj_restriction,
399 op: TokenType::Implies,
400 right: verb_pred,
401 }),
402 ),
403 _ => (
404 QuantifierKind::Existential,
405 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
406 left: obj_restriction,
407 op: TokenType::And,
408 right: verb_pred,
409 }),
410 ),
411 };
412
413 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
414 kind,
415 variable: obj_var,
416 body,
417 island_id: self.current_island,
418 });
419
420 let effective_time = self.pending_time.take().unwrap_or(Time::None);
421 let with_time = match effective_time {
422 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
423 operator: TemporalOperator::Past,
424 body: quantified,
425 }),
426 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
427 operator: TemporalOperator::Future,
428 body: quantified,
429 }),
430 _ => quantified,
431 };
432
433 self.negative_depth -= 1;
434 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
435 op: TokenType::Not,
436 operand: with_time,
437 }));
438 }
439
440 if self.check_npi_object() {
441 let npi_token = self.advance().kind.clone();
442 let obj_var = self.next_var_name();
443
444 let restriction_name = match npi_token {
445 TokenType::Anything => "Thing",
446 TokenType::Anyone => "Person",
447 _ => "Thing",
448 };
449
450 let restriction_sym = self.interner.intern(restriction_name);
451 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
452 name: restriction_sym,
453 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
454 world: None,
455 });
456
457 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
458 name: verb,
459 args: self.ctx.terms.alloc_slice([subject_term, Term::Variable(obj_var)]),
460 world: None,
461 });
462
463 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
464 left: obj_restriction,
465 op: TokenType::And,
466 right: verb_pred,
467 });
468
469 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
470 kind: QuantifierKind::Existential,
471 variable: obj_var,
472 body,
473 island_id: self.current_island,
474 });
475
476 let effective_time = self.pending_time.take().unwrap_or(Time::None);
477 let with_time = match effective_time {
478 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
479 operator: TemporalOperator::Past,
480 body: quantified,
481 }),
482 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
483 operator: TemporalOperator::Future,
484 body: quantified,
485 }),
486 _ => quantified,
487 };
488
489 self.negative_depth -= 1;
490 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
491 op: TokenType::Not,
492 operand: with_time,
493 }));
494 }
495
496 let mut roles: Vec<(ThematicRole, Term<'a>)> =
497 vec![(ThematicRole::Agent, subject_term)];
498
499 if self.check_content_word() || self.check_article() || self.check_pronoun() {
501 if self.check_pronoun() {
502 let pronoun_token = self.advance().clone();
504 let term = if let TokenType::Pronoun { gender, number, .. } = pronoun_token.kind {
505 let resolved = self.resolve_pronoun(gender, number)?;
506 match resolved {
507 super::ResolvedPronoun::Variable(s) => Term::Variable(s),
508 super::ResolvedPronoun::Constant(s) => Term::Constant(s),
509 }
510 } else {
511 Term::Constant(pronoun_token.lexeme)
513 };
514 roles.push((ThematicRole::Theme, term));
515 } else {
516 let object = self.parse_noun_phrase(false)?;
517 let object_term = self.noun_phrase_to_term(&object);
518 roles.push((ThematicRole::Theme, object_term));
519 }
520 }
521
522 let event_var = self.get_event_var();
523 let suppress_existential = self.drs.in_conditional_antecedent();
524 let effective_time = self.pending_time.take().unwrap_or(Time::None);
525 let mut modifiers = Vec::new();
526 match effective_time {
527 Time::Past => modifiers.push(self.interner.intern("Past")),
528 Time::Future => modifiers.push(self.interner.intern("Future")),
529 _ => {}
530 }
531
532 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
533 event_var,
534 verb,
535 roles: self.ctx.roles.alloc_slice(roles),
536 modifiers: self.ctx.syms.alloc_slice(modifiers),
537 suppress_existential,
538 world: None,
539 })));
540
541 self.negative_depth -= 1;
542 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
543 op: TokenType::Not,
544 operand: neo_event,
545 }));
546 }
547
548 self.negative_depth -= 1;
549 }
550 }
551
552 if self.check(&TokenType::Is)
553 || self.check(&TokenType::Are)
554 || self.check(&TokenType::Was)
555 || self.check(&TokenType::Were)
556 {
557 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
558 Time::Past
559 } else {
560 Time::Present
561 };
562 self.advance();
563
564 let is_negated = self.check(&TokenType::Not);
566 if is_negated {
567 self.advance(); }
569
570 let mut copula_temporal: Option<super::CopulaTemporal> = None;
572 if !is_negated {
573 if self.check(&TokenType::Never) {
574 self.advance();
575 copula_temporal = Some(super::CopulaTemporal::Never);
576 } else if let TokenType::Adverb(sym) | TokenType::ScopalAdverb(sym) | TokenType::TemporalAdverb(sym) = &self.peek().kind {
577 let resolved = self.interner.resolve(*sym).to_string();
578 if resolved == "Always" || resolved == "always" {
579 self.advance();
580 copula_temporal = Some(super::CopulaTemporal::Always);
581 } else if resolved == "Eventually" || resolved == "eventually" {
582 self.advance();
583 copula_temporal = Some(super::CopulaTemporal::Eventually);
584 }
585 }
586 }
587
588 if self.check_verb() {
589 let (verb, _verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
590
591 if verb_class.is_stative() && verb_aspect == Aspect::Progressive {
593 return Err(crate::error::ParseError {
594 kind: crate::error::ParseErrorKind::StativeProgressiveConflict,
595 span: self.current_span(),
596 });
597 }
598
599 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
600 name: verb,
601 args: self.ctx.terms.alloc_slice([subject_term]),
602 world: None,
603 });
604
605 let with_aspect = if verb_aspect == Aspect::Progressive {
606 let operator = if verb_class == crate::lexicon::VerbClass::Semelfactive {
608 AspectOperator::Iterative
609 } else {
610 AspectOperator::Progressive
611 };
612 self.ctx.exprs.alloc(LogicExpr::Aspectual {
613 operator,
614 body: predicate,
615 })
616 } else {
617 predicate
618 };
619
620 let with_time = if copula_time == Time::Past {
621 self.ctx.exprs.alloc(LogicExpr::Temporal {
622 operator: TemporalOperator::Past,
623 body: with_aspect,
624 })
625 } else {
626 with_aspect
627 };
628
629 let with_neg = if is_negated {
630 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
631 op: TokenType::Not,
632 operand: with_time,
633 })
634 } else {
635 with_time
636 };
637
638 let result = match copula_temporal {
639 Some(super::CopulaTemporal::Always) => {
640 self.ctx.exprs.alloc(LogicExpr::Temporal {
641 operator: TemporalOperator::Always,
642 body: with_neg,
643 })
644 }
645 Some(super::CopulaTemporal::Never) => {
646 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
647 op: TokenType::Not,
648 operand: with_time,
649 });
650 self.ctx.exprs.alloc(LogicExpr::Temporal {
651 operator: TemporalOperator::Always,
652 body: negated,
653 })
654 }
655 Some(super::CopulaTemporal::Eventually) => {
656 self.ctx.exprs.alloc(LogicExpr::Temporal {
657 operator: TemporalOperator::Eventually,
658 body: with_neg,
659 })
660 }
661 None => with_neg,
662 };
663
664 return Ok(result);
665 }
666
667 let predicate = self.consume_content_word()?;
668 let base_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
669 name: predicate,
670 args: self.ctx.terms.alloc_slice([subject_term]),
671 world: None,
672 });
673
674 let with_time = if copula_time == Time::Past {
675 self.ctx.exprs.alloc(LogicExpr::Temporal {
676 operator: TemporalOperator::Past,
677 body: base_pred,
678 })
679 } else {
680 base_pred
681 };
682
683 let with_neg = if is_negated {
684 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
685 op: TokenType::Not,
686 operand: with_time,
687 })
688 } else {
689 with_time
690 };
691
692 let result = match copula_temporal {
693 Some(super::CopulaTemporal::Always) => {
694 self.ctx.exprs.alloc(LogicExpr::Temporal {
695 operator: TemporalOperator::Always,
696 body: with_neg,
697 })
698 }
699 Some(super::CopulaTemporal::Never) => {
700 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
701 op: TokenType::Not,
702 operand: with_time,
703 });
704 self.ctx.exprs.alloc(LogicExpr::Temporal {
705 operator: TemporalOperator::Always,
706 body: negated,
707 })
708 }
709 Some(super::CopulaTemporal::Eventually) => {
710 self.ctx.exprs.alloc(LogicExpr::Temporal {
711 operator: TemporalOperator::Eventually,
712 body: with_neg,
713 })
714 }
715 None => with_neg,
716 };
717
718 return Ok(result);
719 }
720
721 if self.check_auxiliary_as_main_verb() {
724 return self.parse_do_as_main_verb(subject_term);
725 }
726
727 if self.check_verb() {
728 let (mut verb, verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
729 let mut args = vec![subject_term.clone()];
730
731 if self.check_wh_word() {
733 let wh_token = self.advance().kind.clone();
734
735 let is_who = matches!(wh_token, TokenType::Who);
736 let is_what = matches!(wh_token, TokenType::What);
737
738 let is_sluicing = self.is_at_end() ||
740 self.check(&TokenType::Period) ||
741 self.check(&TokenType::Comma);
742
743 if is_sluicing {
744 if let Some(template) = self.last_event_template.clone() {
745 let wh_var = self.next_var_name();
746
747 let roles: Vec<_> = if is_who {
748 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
749 .chain(template.non_agent_roles.iter().cloned())
750 .collect()
751 } else if is_what {
752 vec![
753 (ThematicRole::Agent, subject_term.clone()),
754 (ThematicRole::Theme, Term::Variable(wh_var)),
755 ]
756 } else {
757 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
758 .chain(template.non_agent_roles.iter().cloned())
759 .collect()
760 };
761
762 let event_var = self.get_event_var();
763 let suppress_existential = self.drs.in_conditional_antecedent();
764 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
765 event_var,
766 verb: template.verb,
767 roles: self.ctx.roles.alloc_slice(roles),
768 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
769 suppress_existential,
770 world: None,
771 })));
772
773 let question = self.ctx.exprs.alloc(LogicExpr::Question {
774 wh_variable: wh_var,
775 body: reconstructed,
776 });
777
778 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
779 event_var: self.get_event_var(),
780 verb,
781 roles: self.ctx.roles.alloc_slice(vec![
782 (ThematicRole::Agent, subject_term),
783 (ThematicRole::Theme, Term::Proposition(question)),
784 ]),
785 modifiers: self.ctx.syms.alloc_slice(vec![]),
786 suppress_existential,
787 world: None,
788 })));
789
790 return Ok(know_event);
791 }
792 }
793
794 let embedded = self.parse_embedded_wh_clause()?;
796 let question = self.ctx.exprs.alloc(LogicExpr::Question {
797 wh_variable: self.interner.intern("x"),
798 body: embedded,
799 });
800
801 let suppress_existential = self.drs.in_conditional_antecedent();
802 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
803 event_var: self.get_event_var(),
804 verb,
805 roles: self.ctx.roles.alloc_slice(vec![
806 (ThematicRole::Agent, subject_term),
807 (ThematicRole::Theme, Term::Proposition(question)),
808 ]),
809 modifiers: self.ctx.syms.alloc_slice(vec![]),
810 suppress_existential,
811 world: None,
812 })));
813
814 return Ok(know_event);
815 }
816
817 let mut object_term: Option<Term<'a>> = None;
818 let mut second_object_term: Option<Term<'a>> = None;
819 let mut object_pps: &[&LogicExpr<'a>] = &[]; if self.check(&TokenType::Reflexive) {
821 self.advance();
822 let term = Term::Constant(subject_symbol);
823 object_term = Some(term);
824 args.push(term);
825 } else if self.check_pronoun() {
826 let token = self.advance().clone();
827 let (gender, number) = match &token.kind {
828 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
829 TokenType::Ambiguous { primary, alternatives } => {
830 if let TokenType::Pronoun { gender, number, .. } = **primary {
831 (gender, number)
832 } else {
833 alternatives.iter().find_map(|t| {
834 if let TokenType::Pronoun { gender, number, .. } = t {
835 Some((*gender, *number))
836 } else {
837 None
838 }
839 }).unwrap_or((Gender::Unknown, Number::Singular))
840 }
841 }
842 _ => (Gender::Unknown, Number::Singular),
843 };
844
845 let resolved = self.resolve_pronoun(gender, number)?;
846 let term = match resolved {
847 super::ResolvedPronoun::Variable(s) => Term::Variable(s),
848 super::ResolvedPronoun::Constant(s) => Term::Constant(s),
849 };
850 object_term = Some(term);
851 args.push(term);
852
853 let verb_str = self.interner.resolve(verb);
854 if Lexer::is_ditransitive_verb(verb_str)
855 && (self.check_content_word() || self.check_article())
856 {
857 let second_np = self.parse_noun_phrase(false)?;
858 let second_term = Term::Constant(second_np.noun);
859 second_object_term = Some(second_term);
860 args.push(second_term);
861 }
862 } else if self.check_quantifier() || self.check_article() {
863 let obj_quantifier = if self.check_quantifier() {
864 Some(self.advance().kind.clone())
865 } else {
866 let art = self.advance().kind.clone();
867 if let TokenType::Article(def) = art {
868 if def == Definiteness::Indefinite {
869 Some(TokenType::Some)
870 } else {
871 None
872 }
873 } else {
874 None
875 }
876 };
877
878 let object_np = self.parse_noun_phrase(false)?;
879
880 if let Some(obj_q) = obj_quantifier {
881 let obj_var = self.next_var_name();
882
883 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
885 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
886 Number::Plural
887 } else {
888 Number::Singular
889 };
890 if object_np.definiteness == Some(Definiteness::Definite) {
892 self.drs.introduce_referent_with_source(obj_var, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
893 } else {
894 self.drs.introduce_referent(obj_var, object_np.noun, obj_gender, obj_number);
895 }
896
897 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
898 name: object_np.noun,
899 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
900 world: None,
901 });
902
903 let event_var = self.get_event_var();
904 let mut modifiers = self.collect_adverbs();
905 let effective_time = self.pending_time.take().unwrap_or(verb_time);
906 match effective_time {
907 Time::Past => modifiers.push(self.interner.intern("Past")),
908 Time::Future => modifiers.push(self.interner.intern("Future")),
909 _ => {}
910 }
911
912 let roles = vec![
913 (ThematicRole::Agent, subject_term),
914 (ThematicRole::Theme, Term::Variable(obj_var)),
915 ];
916
917 let suppress_existential = self.drs.in_conditional_antecedent();
918 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
919 event_var,
920 verb,
921 roles: self.ctx.roles.alloc_slice(roles),
922 modifiers: self.ctx.syms.alloc_slice(modifiers),
923 suppress_existential,
924 world: None,
925 })));
926
927 let obj_kind = match obj_q {
928 TokenType::All => QuantifierKind::Universal,
929 TokenType::Some => QuantifierKind::Existential,
930 TokenType::No => QuantifierKind::Universal,
931 TokenType::Most => QuantifierKind::Most,
932 TokenType::Few => QuantifierKind::Few,
933 TokenType::Many => QuantifierKind::Many,
934 TokenType::Cardinal(n) => QuantifierKind::Cardinal(n),
935 TokenType::AtLeast(n) => QuantifierKind::AtLeast(n),
936 TokenType::AtMost(n) => QuantifierKind::AtMost(n),
937 _ => QuantifierKind::Existential,
938 };
939
940 let obj_body = match obj_q {
941 TokenType::All => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
942 left: obj_restriction,
943 op: TokenType::Implies,
944 right: neo_event,
945 }),
946 TokenType::No => {
947 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
948 op: TokenType::Not,
949 operand: neo_event,
950 });
951 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
952 left: obj_restriction,
953 op: TokenType::Implies,
954 right: neg,
955 })
956 }
957 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
958 left: obj_restriction,
959 op: TokenType::And,
960 right: neo_event,
961 }),
962 };
963
964 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
965 kind: obj_kind,
966 variable: obj_var,
967 body: obj_body,
968 island_id: self.current_island,
969 }));
970 } else {
971 if object_np.definiteness == Some(Definiteness::Definite) {
975 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
976 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
977 Number::Plural
978 } else {
979 Number::Singular
980 };
981 self.drs.introduce_referent_with_source(object_np.noun, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
983 }
984
985 let term = Term::Constant(object_np.noun);
986 object_term = Some(term);
987 object_pps = object_np.pps;
989 args.push(term);
990 }
991 } else if self.check_focus() {
992 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
993 k
994 } else {
995 FocusKind::Only
996 };
997
998 let event_var = self.get_event_var();
999 let mut modifiers = self.collect_adverbs();
1000 let effective_time = self.pending_time.take().unwrap_or(verb_time);
1001 match effective_time {
1002 Time::Past => modifiers.push(self.interner.intern("Past")),
1003 Time::Future => modifiers.push(self.interner.intern("Future")),
1004 _ => {}
1005 }
1006
1007 if self.check_preposition() {
1008 let prep_token = self.advance().clone();
1009 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
1010 sym
1011 } else {
1012 self.interner.intern("to")
1013 };
1014 let pp_obj = self.parse_noun_phrase(false)?;
1015 let pp_obj_term = Term::Constant(pp_obj.noun);
1016
1017 let roles = vec![(ThematicRole::Agent, subject_term)];
1018 let suppress_existential = self.drs.in_conditional_antecedent();
1019 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
1020 event_var,
1021 verb,
1022 roles: self.ctx.roles.alloc_slice(roles),
1023 modifiers: self.ctx.syms.alloc_slice(modifiers),
1024 suppress_existential,
1025 world: None,
1026 })));
1027
1028 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1029 name: prep_name,
1030 args: self.ctx.terms.alloc_slice([Term::Variable(event_var), pp_obj_term]),
1031 world: None,
1032 });
1033
1034 let with_pp = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1035 left: neo_event,
1036 op: TokenType::And,
1037 right: pp_pred,
1038 });
1039
1040 let focused_ref = self.ctx.terms.alloc(pp_obj_term);
1041 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
1042 kind: focus_kind,
1043 focused: focused_ref,
1044 scope: with_pp,
1045 }));
1046 }
1047
1048 let focused_np = self.parse_noun_phrase(false)?;
1049 let focused_term = Term::Constant(focused_np.noun);
1050 args.push(focused_term);
1051
1052 let roles = vec![
1053 (ThematicRole::Agent, subject_term),
1054 (ThematicRole::Theme, focused_term),
1055 ];
1056
1057 let suppress_existential = self.drs.in_conditional_antecedent();
1058 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
1059 event_var,
1060 verb,
1061 roles: self.ctx.roles.alloc_slice(roles),
1062 modifiers: self.ctx.syms.alloc_slice(modifiers),
1063 suppress_existential,
1064 world: None,
1065 })));
1066
1067 let focused_ref = self.ctx.terms.alloc(focused_term);
1068 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
1069 kind: focus_kind,
1070 focused: focused_ref,
1071 scope: neo_event,
1072 }));
1073 } else if self.check_number() {
1074 let measure = self.parse_measure_phrase()?;
1075 if self.check_content_word() {
1076 let noun_sym = self.consume_content_word()?;
1077 args.push(*measure);
1078 args.push(Term::Constant(noun_sym));
1079 } else {
1080 args.push(*measure);
1081 }
1082 } else if self.check_content_word() {
1083 let potential_object = self.parse_noun_phrase(false)?;
1084 object_pps = potential_object.pps;
1086
1087 if self.check_verb() && self.filler_gap.is_some() {
1088 let embedded_subject = potential_object.noun;
1089 let embedded_pred = self.parse_predicate_with_subject(embedded_subject)?;
1090
1091 let embedded_term = Term::Proposition(embedded_pred);
1092 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1093 name: verb,
1094 args: self.ctx.terms.alloc_slice([subject_term, embedded_term]),
1095 world: None,
1096 });
1097
1098 let effective_time = self.pending_time.take().unwrap_or(verb_time);
1099 return Ok(if effective_time == Time::Past {
1100 self.ctx.exprs.alloc(LogicExpr::Temporal {
1101 operator: TemporalOperator::Past,
1102 body: main_pred,
1103 })
1104 } else {
1105 main_pred
1106 });
1107 }
1108
1109 let mut all_objects: Vec<Symbol> = vec![potential_object.noun];
1111
1112 while self.check(&TokenType::And) {
1114 let saved = self.current;
1115 self.advance(); if self.check_content_word() || self.check_article() {
1117 let next_obj = match self.parse_noun_phrase(false) {
1118 Ok(np) => np,
1119 Err(_) => {
1120 self.current = saved;
1121 break;
1122 }
1123 };
1124 all_objects.push(next_obj.noun);
1125 } else {
1126 self.current = saved;
1127 break;
1128 }
1129 }
1130
1131 if self.check(&TokenType::Respectively) {
1133 let respectively_span = self.peek().span;
1134 if all_objects.len() > 1 {
1136 return Err(ParseError {
1137 kind: ParseErrorKind::RespectivelyLengthMismatch {
1138 subject_count: 1,
1139 object_count: all_objects.len(),
1140 },
1141 span: respectively_span,
1142 });
1143 }
1144 self.advance(); }
1147
1148 let term = Term::Constant(all_objects[0]);
1150 object_term = Some(term);
1151 args.push(term);
1152
1153 if all_objects.len() > 1 {
1155 let obj_members: Vec<Term<'a>> = all_objects.iter()
1156 .map(|o| Term::Constant(*o))
1157 .collect();
1158 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
1159 args.pop();
1161 args.push(obj_group);
1162 }
1163
1164 let verb_str = self.interner.resolve(verb);
1165 if Lexer::is_ditransitive_verb(verb_str)
1166 && (self.check_content_word() || self.check_article())
1167 {
1168 let second_np = self.parse_noun_phrase(false)?;
1169 let second_term = Term::Constant(second_np.noun);
1170 second_object_term = Some(second_term);
1171 args.push(second_term);
1172 }
1173 } else if self.filler_gap.is_some() && !self.check_content_word() && !self.check_pronoun()
1174 {
1175 let gap_var = self.filler_gap.take().unwrap();
1176 let term = Term::Variable(gap_var);
1177 object_term = Some(term);
1178 args.push(term);
1179 }
1180
1181 if let TokenType::Particle(particle_sym) = self.peek().kind {
1183 let verb_str = self.interner.resolve(verb).to_lowercase();
1184 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
1185 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
1186 self.advance(); verb = self.interner.intern(phrasal_lemma);
1188 }
1189 }
1190
1191 let unknown = self.interner.intern("?");
1192 let mut pp_predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
1193 while self.check_preposition() || self.check_to() {
1194 if self.check_preposition_is("within") && self.current + 1 < self.tokens.len()
1196 && matches!(self.tokens[self.current + 1].kind, TokenType::Cardinal(_) | TokenType::Number(_))
1197 {
1198 break;
1199 }
1200 let prep_token = self.advance().clone();
1201 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
1202 sym
1203 } else if matches!(prep_token.kind, TokenType::To) {
1204 self.interner.intern("To")
1205 } else {
1206 continue;
1207 };
1208
1209 let pp_obj_term = if self.check(&TokenType::Reflexive) {
1210 self.advance();
1211 Term::Constant(subject_symbol)
1212 } else if self.check_pronoun() {
1213 let token = self.advance().clone();
1214 let (gender, number) = match &token.kind {
1215 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
1216 TokenType::Ambiguous { primary, alternatives } => {
1217 if let TokenType::Pronoun { gender, number, .. } = **primary {
1218 (gender, number)
1219 } else {
1220 alternatives.iter().find_map(|t| {
1221 if let TokenType::Pronoun { gender, number, .. } = t {
1222 Some((*gender, *number))
1223 } else {
1224 None
1225 }
1226 }).unwrap_or((Gender::Unknown, Number::Singular))
1227 }
1228 }
1229 _ => (Gender::Unknown, Number::Singular),
1230 };
1231 let resolved = self.resolve_pronoun(gender, number)?;
1232 match resolved {
1233 super::ResolvedPronoun::Variable(s) => Term::Variable(s),
1234 super::ResolvedPronoun::Constant(s) => Term::Constant(s),
1235 }
1236 } else if self.check_content_word() || self.check_article() {
1237 let prep_obj = self.parse_noun_phrase(false)?;
1238 Term::Constant(prep_obj.noun)
1239 } else {
1240 continue;
1241 };
1242
1243 if self.pp_attach_to_noun {
1244 if let Some(obj) = object_term {
1245 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1246 name: prep_name,
1247 args: self.ctx.terms.alloc_slice([obj, pp_obj_term]),
1248 world: None,
1249 });
1250 pp_predicates.push(pp_pred);
1251 } else {
1252 args.push(pp_obj_term);
1253 }
1254 } else {
1255 let event_sym = self.get_event_var();
1256 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1257 name: prep_name,
1258 args: self
1259 .ctx
1260 .terms
1261 .alloc_slice([Term::Variable(event_sym), pp_obj_term]),
1262 world: None,
1263 });
1264 pp_predicates.push(pp_pred);
1265 }
1266 }
1267
1268 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
1269 self.advance();
1270 let rel_var = self.next_var_name();
1271 let rel_pred = self.parse_relative_clause(rel_var)?;
1272 pp_predicates.push(rel_pred);
1273 }
1274
1275 let mut modifiers = self.collect_adverbs();
1276
1277 let effective_time = self.pending_time.take().unwrap_or(verb_time);
1278 match effective_time {
1279 Time::Past => modifiers.push(self.interner.intern("Past")),
1280 Time::Future => modifiers.push(self.interner.intern("Future")),
1281 _ => {}
1282 }
1283
1284 if verb_aspect == Aspect::Progressive {
1285 modifiers.push(self.interner.intern("Progressive"));
1286 } else if verb_aspect == Aspect::Perfect {
1287 modifiers.push(self.interner.intern("Perfect"));
1288 }
1289
1290 let mut roles: Vec<(ThematicRole, Term<'a>)> = Vec::new();
1291
1292 let verb_str = self.interner.resolve(verb).to_lowercase();
1294 let is_unaccusative = crate::lexicon::lookup_verb_db(&verb_str)
1295 .map(|meta| meta.features.contains(&crate::lexicon::Feature::Unaccusative))
1296 .unwrap_or(false);
1297
1298 let has_object = object_term.is_some() || second_object_term.is_some();
1301 let subject_role = if is_unaccusative && !has_object {
1302 ThematicRole::Theme
1303 } else {
1304 ThematicRole::Agent
1305 };
1306
1307 roles.push((subject_role, subject_term));
1308 if let Some(second_obj) = second_object_term {
1309 if let Some(first_obj) = object_term {
1310 roles.push((ThematicRole::Recipient, first_obj));
1311 }
1312 roles.push((ThematicRole::Theme, second_obj));
1313 } else if let Some(obj) = object_term {
1314 roles.push((ThematicRole::Theme, obj));
1315 }
1316
1317 let event_var = self.get_event_var();
1318 let suppress_existential = self.drs.in_conditional_antecedent();
1319 if suppress_existential {
1320 let event_class = self.interner.intern("Event");
1321 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
1322 }
1323 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
1324 event_var,
1325 verb,
1326 roles: self.ctx.roles.alloc_slice(roles.clone()),
1327 modifiers: self.ctx.syms.alloc_slice(modifiers.clone()),
1328 suppress_existential,
1329 world: None,
1330 })));
1331
1332 self.capture_event_template(verb, &roles, &modifiers);
1334
1335 let with_pps = if pp_predicates.is_empty() {
1336 neo_event
1337 } else {
1338 let mut combined = neo_event;
1339 for pp in pp_predicates {
1340 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1341 left: combined,
1342 op: TokenType::And,
1343 right: pp,
1344 });
1345 }
1346 combined
1347 };
1348
1349 let with_object_pps = if object_pps.is_empty() {
1352 with_pps
1353 } else if let Some(obj_term) = object_term {
1354 let placeholder = self.interner.intern("_PP_SELF_");
1355 let mut combined = with_pps;
1356 for pp in object_pps {
1357 let substituted = match pp {
1359 LogicExpr::Predicate { name, args, .. } => {
1360 let new_args: Vec<Term<'a>> = args
1361 .iter()
1362 .map(|arg| match arg {
1363 Term::Variable(v) if *v == placeholder => obj_term,
1364 other => *other,
1365 })
1366 .collect();
1367 self.ctx.exprs.alloc(LogicExpr::Predicate {
1368 name: *name,
1369 args: self.ctx.terms.alloc_slice(new_args),
1370 world: None,
1371 })
1372 }
1373 _ => *pp,
1374 };
1375 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1376 left: combined,
1377 op: TokenType::And,
1378 right: substituted,
1379 });
1380 }
1381 combined
1382 } else {
1383 with_pps
1384 };
1385
1386 let with_aspect = if verb_aspect == Aspect::Simple && effective_time == Time::Present {
1388 if !verb_class.is_stative() {
1390 self.ctx.exprs.alloc(LogicExpr::Aspectual {
1391 operator: AspectOperator::Habitual,
1392 body: with_object_pps,
1393 })
1394 } else {
1395 with_object_pps
1396 }
1397 } else if verb_aspect == Aspect::Progressive {
1398 if verb_class == crate::lexicon::VerbClass::Semelfactive {
1400 self.ctx.exprs.alloc(LogicExpr::Aspectual {
1401 operator: AspectOperator::Iterative,
1402 body: with_object_pps,
1403 })
1404 } else {
1405 with_object_pps
1406 }
1407 } else {
1408 with_object_pps
1409 };
1410
1411 Ok(with_aspect)
1412 } else {
1413 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject_symbol)))
1414 }
1415 }
1416}
1417
1418impl<'a, 'ctx, 'int> LogicVerbParsing<'a, 'ctx, 'int> for Parser<'a, 'ctx, 'int> {
1419 fn parse_predicate_with_subject(&mut self, subject_symbol: Symbol) -> ParseResult<&'a LogicExpr<'a>> {
1420 let result = self.parse_predicate_impl(subject_symbol, false)?;
1421 Ok(self.try_wrap_bounded_delay(result))
1422 }
1423
1424 fn parse_predicate_with_subject_as_var(&mut self, subject_symbol: Symbol) -> ParseResult<&'a LogicExpr<'a>> {
1425 let result = self.parse_predicate_impl(subject_symbol, true)?;
1426 Ok(self.try_wrap_bounded_delay(result))
1427 }
1428
1429 fn try_parse_plural_subject(
1430 &mut self,
1431 first_subject: &NounPhrase<'a>,
1432 ) -> Result<Option<&'a LogicExpr<'a>>, ParseError> {
1433 let saved_pos = self.current;
1434
1435 self.advance();
1437
1438 if !self.check_content_word() {
1439 self.current = saved_pos;
1440 return Ok(None);
1441 }
1442
1443 let mut subjects: Vec<Symbol> = vec![first_subject.noun];
1445
1446 loop {
1447 if !self.check_content_word() {
1448 break;
1449 }
1450 let next_subject = match self.parse_noun_phrase(true) {
1451 Ok(np) => np,
1452 Err(_) => {
1453 self.current = saved_pos;
1454 return Ok(None);
1455 }
1456 };
1457 subjects.push(next_subject.noun);
1458
1459 if self.check(&TokenType::And) {
1460 self.advance();
1461 } else {
1462 break;
1463 }
1464 }
1465
1466 if self.check(&TokenType::Is) || self.check(&TokenType::Are)
1469 || self.check(&TokenType::Was) || self.check(&TokenType::Were)
1470 {
1471 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
1472 Time::Past
1473 } else {
1474 Time::Present
1475 };
1476 self.advance(); let is_negated = self.check(&TokenType::Not);
1480 if is_negated {
1481 self.advance(); }
1483
1484 let has_both = self.check(&TokenType::Both);
1488 if has_both {
1489 self.advance(); }
1491
1492 if !self.check_content_word() && !self.check_article() {
1494 self.current = saved_pos;
1495 return Ok(None);
1496 }
1497
1498 let predicate_np = match self.parse_noun_phrase(false) {
1499 Ok(np) => np,
1500 Err(_) => {
1501 self.current = saved_pos;
1502 return Ok(None);
1503 }
1504 };
1505 let predicate = predicate_np.noun;
1506
1507 let mut conjuncts: Vec<&'a LogicExpr<'a>> = Vec::new();
1509 for subj in &subjects {
1510 let pred_expr = self.ctx.exprs.alloc(LogicExpr::Predicate {
1511 name: predicate,
1512 args: self.ctx.terms.alloc_slice([Term::Constant(*subj)]),
1513 world: None,
1514 });
1515 conjuncts.push(pred_expr);
1516 }
1517
1518 if is_negated && !has_both {
1519 for conjunct in &mut conjuncts {
1521 *conjunct = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
1522 op: TokenType::Not,
1523 operand: *conjunct,
1524 });
1525 }
1526 }
1527
1528 let mut result = conjuncts[0];
1530 for conjunct in &conjuncts[1..] {
1531 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1532 left: result,
1533 op: TokenType::And,
1534 right: *conjunct,
1535 });
1536 }
1537
1538 if is_negated && has_both {
1540 result = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
1541 op: TokenType::Not,
1542 operand: result,
1543 });
1544 }
1545
1546 let with_time = match copula_time {
1548 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1549 operator: TemporalOperator::Past,
1550 body: result,
1551 }),
1552 _ => result,
1553 };
1554
1555 return Ok(Some(with_time));
1556 }
1557
1558 if !self.check_verb() {
1559 self.current = saved_pos;
1560 return Ok(None);
1561 }
1562
1563 let (verb, verb_time, _verb_aspect, _) = self.consume_verb_with_metadata();
1566
1567 if self.check(&TokenType::Reciprocal) {
1569 self.advance();
1570 if subjects.len() != 2 {
1571 self.current = saved_pos;
1572 return Ok(None);
1573 }
1574 let pred1 = self.ctx.exprs.alloc(LogicExpr::Predicate {
1575 name: verb,
1576 args: self.ctx.terms.alloc_slice([
1577 Term::Constant(subjects[0]),
1578 Term::Constant(subjects[1]),
1579 ]),
1580 world: None,
1581 });
1582 let pred2 = self.ctx.exprs.alloc(LogicExpr::Predicate {
1583 name: verb,
1584 args: self.ctx.terms.alloc_slice([
1585 Term::Constant(subjects[1]),
1586 Term::Constant(subjects[0]),
1587 ]),
1588 world: None,
1589 });
1590 let expr = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1591 left: pred1,
1592 op: TokenType::And,
1593 right: pred2,
1594 });
1595
1596 let with_time = match verb_time {
1597 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1598 operator: TemporalOperator::Past,
1599 body: expr,
1600 }),
1601 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1602 operator: TemporalOperator::Future,
1603 body: expr,
1604 }),
1605 _ => expr,
1606 };
1607 return Ok(Some(with_time));
1608 }
1609
1610 let mut objects: Vec<Symbol> = Vec::new();
1612 if self.check_content_word() || self.check_article() {
1613 let first_obj = match self.parse_noun_phrase(false) {
1615 Ok(np) => np,
1616 Err(_) => {
1617 return Ok(Some(self.build_group_predicate(&subjects, verb, verb_time)));
1619 }
1620 };
1621 objects.push(first_obj.noun);
1622
1623 while self.check(&TokenType::And) {
1625 self.advance();
1626 if self.check_content_word() || self.check_article() {
1627 let next_obj = match self.parse_noun_phrase(false) {
1628 Ok(np) => np,
1629 Err(_) => break,
1630 };
1631 objects.push(next_obj.noun);
1632 } else {
1633 break;
1634 }
1635 }
1636 }
1637
1638 if self.check(&TokenType::Respectively) {
1640 let respectively_span = self.peek().span;
1641 self.advance(); if subjects.len() != objects.len() {
1644 return Err(ParseError {
1645 kind: ParseErrorKind::RespectivelyLengthMismatch {
1646 subject_count: subjects.len(),
1647 object_count: objects.len(),
1648 },
1649 span: respectively_span,
1650 });
1651 }
1652
1653 let mut conjuncts: Vec<&'a LogicExpr<'a>> = Vec::new();
1655 let suppress_existential = self.drs.in_conditional_antecedent();
1656 for (subj, obj) in subjects.iter().zip(objects.iter()) {
1657 let event_var = self.get_event_var();
1658 let roles = vec![
1659 (ThematicRole::Agent, Term::Constant(*subj)),
1660 (ThematicRole::Theme, Term::Constant(*obj)),
1661 ];
1662 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
1663 event_var,
1664 verb,
1665 roles: self.ctx.roles.alloc_slice(roles),
1666 modifiers: self.ctx.syms.alloc_slice(vec![]),
1667 suppress_existential,
1668 world: None,
1669 })));
1670 conjuncts.push(neo_event);
1671 }
1672
1673 let mut result = conjuncts[0];
1675 for conjunct in &conjuncts[1..] {
1676 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1677 left: result,
1678 op: TokenType::And,
1679 right: *conjunct,
1680 });
1681 }
1682
1683 let with_time = match verb_time {
1685 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1686 operator: TemporalOperator::Past,
1687 body: result,
1688 }),
1689 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1690 operator: TemporalOperator::Future,
1691 body: result,
1692 }),
1693 _ => result,
1694 };
1695
1696 return Ok(Some(with_time));
1697 }
1698
1699 if objects.is_empty() {
1701 Ok(Some(self.build_group_predicate(&subjects, verb, verb_time)))
1703 } else {
1704 Ok(Some(self.build_group_transitive(&subjects, &objects, verb, verb_time)))
1706 }
1707 }
1708
1709 fn build_group_predicate(
1711 &mut self,
1712 subjects: &[Symbol],
1713 verb: Symbol,
1714 verb_time: Time,
1715 ) -> &'a LogicExpr<'a> {
1716 let group_members: Vec<Term<'a>> = subjects.iter()
1717 .map(|s| Term::Constant(*s))
1718 .collect();
1719 let group_members_slice = self.ctx.terms.alloc_slice(group_members);
1720
1721 let expr = self.ctx.exprs.alloc(LogicExpr::Predicate {
1722 name: verb,
1723 args: self.ctx.terms.alloc_slice([Term::Group(group_members_slice)]),
1724 world: None,
1725 });
1726
1727 match verb_time {
1728 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1729 operator: TemporalOperator::Past,
1730 body: expr,
1731 }),
1732 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1733 operator: TemporalOperator::Future,
1734 body: expr,
1735 }),
1736 _ => expr,
1737 }
1738 }
1739
1740 fn build_group_transitive(
1742 &mut self,
1743 subjects: &[Symbol],
1744 objects: &[Symbol],
1745 verb: Symbol,
1746 verb_time: Time,
1747 ) -> &'a LogicExpr<'a> {
1748 let subj_members: Vec<Term<'a>> = subjects.iter()
1749 .map(|s| Term::Constant(*s))
1750 .collect();
1751 let obj_members: Vec<Term<'a>> = objects.iter()
1752 .map(|o| Term::Constant(*o))
1753 .collect();
1754
1755 let subj_group = Term::Group(self.ctx.terms.alloc_slice(subj_members));
1756 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
1757
1758 let expr = self.ctx.exprs.alloc(LogicExpr::Predicate {
1759 name: verb,
1760 args: self.ctx.terms.alloc_slice([subj_group, obj_group]),
1761 world: None,
1762 });
1763
1764 match verb_time {
1765 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1766 operator: TemporalOperator::Past,
1767 body: expr,
1768 }),
1769 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1770 operator: TemporalOperator::Future,
1771 body: expr,
1772 }),
1773 _ => expr,
1774 }
1775 }
1776
1777 fn parse_control_structure(
1778 &mut self,
1779 subject: &NounPhrase<'a>,
1780 verb: Symbol,
1781 verb_time: Time,
1782 ) -> ParseResult<&'a LogicExpr<'a>> {
1783 let subject_sym = subject.noun;
1784 let verb_str = self.interner.resolve(verb);
1785
1786 if Lexer::is_raising_verb(verb_str) {
1787 if !self.check_to() {
1788 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
1789 name: verb,
1790 args: self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1791 world: None,
1792 }));
1793 }
1794 self.advance();
1795
1796 if !self.check_verb() {
1797 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
1798 name: verb,
1799 args: self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1800 world: None,
1801 }));
1802 }
1803
1804 let inf_verb = self.consume_verb();
1805
1806 let embedded = if self.is_control_verb(inf_verb) {
1807 let raised_np = NounPhrase {
1808 noun: subject_sym,
1809 definiteness: None,
1810 adjectives: &[],
1811 possessor: None,
1812 pps: &[],
1813 superlative: None,
1814 };
1815 self.parse_control_structure(&raised_np, inf_verb, Time::None)?
1816 } else {
1817 self.ctx.exprs.alloc(LogicExpr::Predicate {
1818 name: inf_verb,
1819 args: self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1820 world: None,
1821 })
1822 };
1823
1824 let result = self.ctx.exprs.alloc(LogicExpr::Scopal {
1825 operator: verb,
1826 body: embedded,
1827 });
1828
1829 return Ok(match verb_time {
1830 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1831 operator: TemporalOperator::Past,
1832 body: result,
1833 }),
1834 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1835 operator: TemporalOperator::Future,
1836 body: result,
1837 }),
1838 _ => result,
1839 });
1840 }
1841
1842 let is_object_control = Lexer::is_object_control_verb(self.interner.resolve(verb));
1843 let (object_term, pro_controller_sym) = if self.check_to() {
1844 (None, subject_sym)
1845 } else if self.check_content_word() {
1846 let object_np = self.parse_noun_phrase(false)?;
1847 let obj_sym = object_np.noun;
1848
1849 let controller = if is_object_control {
1850 obj_sym
1851 } else {
1852 subject_sym
1853 };
1854 (
1855 Some(self.ctx.terms.alloc(Term::Constant(obj_sym))),
1856 controller,
1857 )
1858 } else {
1859 (None, subject_sym)
1860 };
1861
1862 if !self.check_to() {
1863 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
1864 name: verb,
1865 args: match object_term {
1866 Some(obj) => self.ctx.terms.alloc_slice([
1867 Term::Constant(subject_sym),
1868 Term::Constant(match obj {
1869 Term::Constant(s) => *s,
1870 _ => subject_sym,
1871 }),
1872 ]),
1873 None => self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1874 },
1875 world: None,
1876 }));
1877 }
1878 self.advance();
1879
1880 if !self.check_verb() {
1881 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
1882 name: verb,
1883 args: self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1884 world: None,
1885 }));
1886 }
1887
1888 let inf_verb = self.consume_verb();
1889 let inf_verb_str = self.interner.resolve(inf_verb).to_lowercase();
1890
1891 let infinitive = if inf_verb_str == "be" && self.check_verb() {
1892 let passive_verb = self.consume_verb();
1893 let passive_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1894 name: passive_verb,
1895 args: self
1896 .ctx
1897 .terms
1898 .alloc_slice([Term::Constant(pro_controller_sym)]),
1899 world: None,
1900 });
1901 self.ctx.voice(crate::ast::VoiceOperator::Passive, passive_pred)
1902 } else if self.is_control_verb(inf_verb) {
1903 let controller_np = NounPhrase {
1904 noun: pro_controller_sym,
1905 definiteness: None,
1906 adjectives: &[],
1907 possessor: None,
1908 pps: &[],
1909 superlative: None,
1910 };
1911 self.parse_control_structure(&controller_np, inf_verb, Time::None)?
1912 } else {
1913 self.ctx.exprs.alloc(LogicExpr::Predicate {
1914 name: inf_verb,
1915 args: self
1916 .ctx
1917 .terms
1918 .alloc_slice([Term::Constant(pro_controller_sym)]),
1919 world: None,
1920 })
1921 };
1922
1923 let control = self.ctx.exprs.alloc(LogicExpr::Control {
1924 verb,
1925 subject: self.ctx.terms.alloc(Term::Constant(subject_sym)),
1926 object: object_term,
1927 infinitive,
1928 });
1929
1930 Ok(match verb_time {
1931 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1932 operator: TemporalOperator::Past,
1933 body: control,
1934 }),
1935 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1936 operator: TemporalOperator::Future,
1937 body: control,
1938 }),
1939 _ => control,
1940 })
1941 }
1942
1943 fn is_control_verb(&self, verb: Symbol) -> bool {
1944 let lemma = self.interner.resolve(verb);
1945 Lexer::is_subject_control_verb(lemma)
1946 || Lexer::is_object_control_verb(lemma)
1947 || Lexer::is_raising_verb(lemma)
1948 }
1949}