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::If,
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::If,
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 if self.check_verb() {
571 let (verb, _verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
572
573 if verb_class.is_stative() && verb_aspect == Aspect::Progressive {
575 return Err(crate::error::ParseError {
576 kind: crate::error::ParseErrorKind::StativeProgressiveConflict,
577 span: self.current_span(),
578 });
579 }
580
581 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
582 name: verb,
583 args: self.ctx.terms.alloc_slice([subject_term]),
584 world: None,
585 });
586
587 let with_aspect = if verb_aspect == Aspect::Progressive {
588 let operator = if verb_class == crate::lexicon::VerbClass::Semelfactive {
590 AspectOperator::Iterative
591 } else {
592 AspectOperator::Progressive
593 };
594 self.ctx.exprs.alloc(LogicExpr::Aspectual {
595 operator,
596 body: predicate,
597 })
598 } else {
599 predicate
600 };
601
602 let with_time = if copula_time == Time::Past {
603 self.ctx.exprs.alloc(LogicExpr::Temporal {
604 operator: TemporalOperator::Past,
605 body: with_aspect,
606 })
607 } else {
608 with_aspect
609 };
610
611 return Ok(if is_negated {
612 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
613 op: TokenType::Not,
614 operand: with_time,
615 })
616 } else {
617 with_time
618 });
619 }
620
621 let predicate = self.consume_content_word()?;
622 let base_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
623 name: predicate,
624 args: self.ctx.terms.alloc_slice([subject_term]),
625 world: None,
626 });
627
628 let with_time = if copula_time == Time::Past {
629 self.ctx.exprs.alloc(LogicExpr::Temporal {
630 operator: TemporalOperator::Past,
631 body: base_pred,
632 })
633 } else {
634 base_pred
635 };
636
637 return Ok(if is_negated {
638 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
639 op: TokenType::Not,
640 operand: with_time,
641 })
642 } else {
643 with_time
644 });
645 }
646
647 if self.check_auxiliary_as_main_verb() {
650 return self.parse_do_as_main_verb(subject_term);
651 }
652
653 if self.check_verb() {
654 let (mut verb, verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
655 let mut args = vec![subject_term.clone()];
656
657 if self.check_wh_word() {
659 let wh_token = self.advance().kind.clone();
660
661 let is_who = matches!(wh_token, TokenType::Who);
662 let is_what = matches!(wh_token, TokenType::What);
663
664 let is_sluicing = self.is_at_end() ||
666 self.check(&TokenType::Period) ||
667 self.check(&TokenType::Comma);
668
669 if is_sluicing {
670 if let Some(template) = self.last_event_template.clone() {
671 let wh_var = self.next_var_name();
672
673 let roles: Vec<_> = if is_who {
674 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
675 .chain(template.non_agent_roles.iter().cloned())
676 .collect()
677 } else if is_what {
678 vec![
679 (ThematicRole::Agent, subject_term.clone()),
680 (ThematicRole::Theme, Term::Variable(wh_var)),
681 ]
682 } else {
683 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
684 .chain(template.non_agent_roles.iter().cloned())
685 .collect()
686 };
687
688 let event_var = self.get_event_var();
689 let suppress_existential = self.drs.in_conditional_antecedent();
690 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
691 event_var,
692 verb: template.verb,
693 roles: self.ctx.roles.alloc_slice(roles),
694 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
695 suppress_existential,
696 world: None,
697 })));
698
699 let question = self.ctx.exprs.alloc(LogicExpr::Question {
700 wh_variable: wh_var,
701 body: reconstructed,
702 });
703
704 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
705 event_var: self.get_event_var(),
706 verb,
707 roles: self.ctx.roles.alloc_slice(vec![
708 (ThematicRole::Agent, subject_term),
709 (ThematicRole::Theme, Term::Proposition(question)),
710 ]),
711 modifiers: self.ctx.syms.alloc_slice(vec![]),
712 suppress_existential,
713 world: None,
714 })));
715
716 return Ok(know_event);
717 }
718 }
719
720 let embedded = self.parse_embedded_wh_clause()?;
722 let question = self.ctx.exprs.alloc(LogicExpr::Question {
723 wh_variable: self.interner.intern("x"),
724 body: embedded,
725 });
726
727 let suppress_existential = self.drs.in_conditional_antecedent();
728 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
729 event_var: self.get_event_var(),
730 verb,
731 roles: self.ctx.roles.alloc_slice(vec![
732 (ThematicRole::Agent, subject_term),
733 (ThematicRole::Theme, Term::Proposition(question)),
734 ]),
735 modifiers: self.ctx.syms.alloc_slice(vec![]),
736 suppress_existential,
737 world: None,
738 })));
739
740 return Ok(know_event);
741 }
742
743 let mut object_term: Option<Term<'a>> = None;
744 let mut second_object_term: Option<Term<'a>> = None;
745 let mut object_pps: &[&LogicExpr<'a>] = &[]; if self.check(&TokenType::Reflexive) {
747 self.advance();
748 let term = Term::Constant(subject_symbol);
749 object_term = Some(term);
750 args.push(term);
751 } else if self.check_pronoun() {
752 let token = self.advance().clone();
753 let (gender, number) = match &token.kind {
754 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
755 TokenType::Ambiguous { primary, alternatives } => {
756 if let TokenType::Pronoun { gender, number, .. } = **primary {
757 (gender, number)
758 } else {
759 alternatives.iter().find_map(|t| {
760 if let TokenType::Pronoun { gender, number, .. } = t {
761 Some((*gender, *number))
762 } else {
763 None
764 }
765 }).unwrap_or((Gender::Unknown, Number::Singular))
766 }
767 }
768 _ => (Gender::Unknown, Number::Singular),
769 };
770
771 let resolved = self.resolve_pronoun(gender, number)?;
772 let term = match resolved {
773 super::ResolvedPronoun::Variable(s) => Term::Variable(s),
774 super::ResolvedPronoun::Constant(s) => Term::Constant(s),
775 };
776 object_term = Some(term);
777 args.push(term);
778
779 let verb_str = self.interner.resolve(verb);
780 if Lexer::is_ditransitive_verb(verb_str)
781 && (self.check_content_word() || self.check_article())
782 {
783 let second_np = self.parse_noun_phrase(false)?;
784 let second_term = Term::Constant(second_np.noun);
785 second_object_term = Some(second_term);
786 args.push(second_term);
787 }
788 } else if self.check_quantifier() || self.check_article() {
789 let obj_quantifier = if self.check_quantifier() {
790 Some(self.advance().kind.clone())
791 } else {
792 let art = self.advance().kind.clone();
793 if let TokenType::Article(def) = art {
794 if def == Definiteness::Indefinite {
795 Some(TokenType::Some)
796 } else {
797 None
798 }
799 } else {
800 None
801 }
802 };
803
804 let object_np = self.parse_noun_phrase(false)?;
805
806 if let Some(obj_q) = obj_quantifier {
807 let obj_var = self.next_var_name();
808
809 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
811 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
812 Number::Plural
813 } else {
814 Number::Singular
815 };
816 if object_np.definiteness == Some(Definiteness::Definite) {
818 self.drs.introduce_referent_with_source(obj_var, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
819 } else {
820 self.drs.introduce_referent(obj_var, object_np.noun, obj_gender, obj_number);
821 }
822
823 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
824 name: object_np.noun,
825 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
826 world: None,
827 });
828
829 let event_var = self.get_event_var();
830 let mut modifiers = self.collect_adverbs();
831 let effective_time = self.pending_time.take().unwrap_or(verb_time);
832 match effective_time {
833 Time::Past => modifiers.push(self.interner.intern("Past")),
834 Time::Future => modifiers.push(self.interner.intern("Future")),
835 _ => {}
836 }
837
838 let roles = vec![
839 (ThematicRole::Agent, subject_term),
840 (ThematicRole::Theme, Term::Variable(obj_var)),
841 ];
842
843 let suppress_existential = self.drs.in_conditional_antecedent();
844 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
845 event_var,
846 verb,
847 roles: self.ctx.roles.alloc_slice(roles),
848 modifiers: self.ctx.syms.alloc_slice(modifiers),
849 suppress_existential,
850 world: None,
851 })));
852
853 let obj_kind = match obj_q {
854 TokenType::All => QuantifierKind::Universal,
855 TokenType::Some => QuantifierKind::Existential,
856 TokenType::No => QuantifierKind::Universal,
857 TokenType::Most => QuantifierKind::Most,
858 TokenType::Few => QuantifierKind::Few,
859 TokenType::Many => QuantifierKind::Many,
860 TokenType::Cardinal(n) => QuantifierKind::Cardinal(n),
861 TokenType::AtLeast(n) => QuantifierKind::AtLeast(n),
862 TokenType::AtMost(n) => QuantifierKind::AtMost(n),
863 _ => QuantifierKind::Existential,
864 };
865
866 let obj_body = match obj_q {
867 TokenType::All => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
868 left: obj_restriction,
869 op: TokenType::If,
870 right: neo_event,
871 }),
872 TokenType::No => {
873 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
874 op: TokenType::Not,
875 operand: neo_event,
876 });
877 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
878 left: obj_restriction,
879 op: TokenType::If,
880 right: neg,
881 })
882 }
883 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
884 left: obj_restriction,
885 op: TokenType::And,
886 right: neo_event,
887 }),
888 };
889
890 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
891 kind: obj_kind,
892 variable: obj_var,
893 body: obj_body,
894 island_id: self.current_island,
895 }));
896 } else {
897 if object_np.definiteness == Some(Definiteness::Definite) {
901 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
902 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
903 Number::Plural
904 } else {
905 Number::Singular
906 };
907 self.drs.introduce_referent_with_source(object_np.noun, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
909 }
910
911 let term = Term::Constant(object_np.noun);
912 object_term = Some(term);
913 object_pps = object_np.pps;
915 args.push(term);
916 }
917 } else if self.check_focus() {
918 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
919 k
920 } else {
921 FocusKind::Only
922 };
923
924 let event_var = self.get_event_var();
925 let mut modifiers = self.collect_adverbs();
926 let effective_time = self.pending_time.take().unwrap_or(verb_time);
927 match effective_time {
928 Time::Past => modifiers.push(self.interner.intern("Past")),
929 Time::Future => modifiers.push(self.interner.intern("Future")),
930 _ => {}
931 }
932
933 if self.check_preposition() {
934 let prep_token = self.advance().clone();
935 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
936 sym
937 } else {
938 self.interner.intern("to")
939 };
940 let pp_obj = self.parse_noun_phrase(false)?;
941 let pp_obj_term = Term::Constant(pp_obj.noun);
942
943 let roles = vec![(ThematicRole::Agent, subject_term)];
944 let suppress_existential = self.drs.in_conditional_antecedent();
945 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
946 event_var,
947 verb,
948 roles: self.ctx.roles.alloc_slice(roles),
949 modifiers: self.ctx.syms.alloc_slice(modifiers),
950 suppress_existential,
951 world: None,
952 })));
953
954 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
955 name: prep_name,
956 args: self.ctx.terms.alloc_slice([Term::Variable(event_var), pp_obj_term]),
957 world: None,
958 });
959
960 let with_pp = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
961 left: neo_event,
962 op: TokenType::And,
963 right: pp_pred,
964 });
965
966 let focused_ref = self.ctx.terms.alloc(pp_obj_term);
967 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
968 kind: focus_kind,
969 focused: focused_ref,
970 scope: with_pp,
971 }));
972 }
973
974 let focused_np = self.parse_noun_phrase(false)?;
975 let focused_term = Term::Constant(focused_np.noun);
976 args.push(focused_term);
977
978 let roles = vec![
979 (ThematicRole::Agent, subject_term),
980 (ThematicRole::Theme, focused_term),
981 ];
982
983 let suppress_existential = self.drs.in_conditional_antecedent();
984 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
985 event_var,
986 verb,
987 roles: self.ctx.roles.alloc_slice(roles),
988 modifiers: self.ctx.syms.alloc_slice(modifiers),
989 suppress_existential,
990 world: None,
991 })));
992
993 let focused_ref = self.ctx.terms.alloc(focused_term);
994 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
995 kind: focus_kind,
996 focused: focused_ref,
997 scope: neo_event,
998 }));
999 } else if self.check_number() {
1000 let measure = self.parse_measure_phrase()?;
1001 if self.check_content_word() {
1002 let noun_sym = self.consume_content_word()?;
1003 args.push(*measure);
1004 args.push(Term::Constant(noun_sym));
1005 } else {
1006 args.push(*measure);
1007 }
1008 } else if self.check_content_word() {
1009 let potential_object = self.parse_noun_phrase(false)?;
1010 object_pps = potential_object.pps;
1012
1013 if self.check_verb() && self.filler_gap.is_some() {
1014 let embedded_subject = potential_object.noun;
1015 let embedded_pred = self.parse_predicate_with_subject(embedded_subject)?;
1016
1017 let embedded_term = Term::Proposition(embedded_pred);
1018 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1019 name: verb,
1020 args: self.ctx.terms.alloc_slice([subject_term, embedded_term]),
1021 world: None,
1022 });
1023
1024 let effective_time = self.pending_time.take().unwrap_or(verb_time);
1025 return Ok(if effective_time == Time::Past {
1026 self.ctx.exprs.alloc(LogicExpr::Temporal {
1027 operator: TemporalOperator::Past,
1028 body: main_pred,
1029 })
1030 } else {
1031 main_pred
1032 });
1033 }
1034
1035 let mut all_objects: Vec<Symbol> = vec![potential_object.noun];
1037
1038 while self.check(&TokenType::And) {
1040 let saved = self.current;
1041 self.advance(); if self.check_content_word() || self.check_article() {
1043 let next_obj = match self.parse_noun_phrase(false) {
1044 Ok(np) => np,
1045 Err(_) => {
1046 self.current = saved;
1047 break;
1048 }
1049 };
1050 all_objects.push(next_obj.noun);
1051 } else {
1052 self.current = saved;
1053 break;
1054 }
1055 }
1056
1057 if self.check(&TokenType::Respectively) {
1059 let respectively_span = self.peek().span;
1060 if all_objects.len() > 1 {
1062 return Err(ParseError {
1063 kind: ParseErrorKind::RespectivelyLengthMismatch {
1064 subject_count: 1,
1065 object_count: all_objects.len(),
1066 },
1067 span: respectively_span,
1068 });
1069 }
1070 self.advance(); }
1073
1074 let term = Term::Constant(all_objects[0]);
1076 object_term = Some(term);
1077 args.push(term);
1078
1079 if all_objects.len() > 1 {
1081 let obj_members: Vec<Term<'a>> = all_objects.iter()
1082 .map(|o| Term::Constant(*o))
1083 .collect();
1084 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
1085 args.pop();
1087 args.push(obj_group);
1088 }
1089
1090 let verb_str = self.interner.resolve(verb);
1091 if Lexer::is_ditransitive_verb(verb_str)
1092 && (self.check_content_word() || self.check_article())
1093 {
1094 let second_np = self.parse_noun_phrase(false)?;
1095 let second_term = Term::Constant(second_np.noun);
1096 second_object_term = Some(second_term);
1097 args.push(second_term);
1098 }
1099 } else if self.filler_gap.is_some() && !self.check_content_word() && !self.check_pronoun()
1100 {
1101 let gap_var = self.filler_gap.take().unwrap();
1102 let term = Term::Variable(gap_var);
1103 object_term = Some(term);
1104 args.push(term);
1105 }
1106
1107 if let TokenType::Particle(particle_sym) = self.peek().kind {
1109 let verb_str = self.interner.resolve(verb).to_lowercase();
1110 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
1111 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
1112 self.advance(); verb = self.interner.intern(phrasal_lemma);
1114 }
1115 }
1116
1117 let unknown = self.interner.intern("?");
1118 let mut pp_predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
1119 while self.check_preposition() || self.check_to() {
1120 let prep_token = self.advance().clone();
1121 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
1122 sym
1123 } else if matches!(prep_token.kind, TokenType::To) {
1124 self.interner.intern("To")
1125 } else {
1126 continue;
1127 };
1128
1129 let pp_obj_term = if self.check(&TokenType::Reflexive) {
1130 self.advance();
1131 Term::Constant(subject_symbol)
1132 } else if self.check_pronoun() {
1133 let token = self.advance().clone();
1134 let (gender, number) = match &token.kind {
1135 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
1136 TokenType::Ambiguous { primary, alternatives } => {
1137 if let TokenType::Pronoun { gender, number, .. } = **primary {
1138 (gender, number)
1139 } else {
1140 alternatives.iter().find_map(|t| {
1141 if let TokenType::Pronoun { gender, number, .. } = t {
1142 Some((*gender, *number))
1143 } else {
1144 None
1145 }
1146 }).unwrap_or((Gender::Unknown, Number::Singular))
1147 }
1148 }
1149 _ => (Gender::Unknown, Number::Singular),
1150 };
1151 let resolved = self.resolve_pronoun(gender, number)?;
1152 match resolved {
1153 super::ResolvedPronoun::Variable(s) => Term::Variable(s),
1154 super::ResolvedPronoun::Constant(s) => Term::Constant(s),
1155 }
1156 } else if self.check_content_word() || self.check_article() {
1157 let prep_obj = self.parse_noun_phrase(false)?;
1158 Term::Constant(prep_obj.noun)
1159 } else {
1160 continue;
1161 };
1162
1163 if self.pp_attach_to_noun {
1164 if let Some(obj) = object_term {
1165 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1166 name: prep_name,
1167 args: self.ctx.terms.alloc_slice([obj, pp_obj_term]),
1168 world: None,
1169 });
1170 pp_predicates.push(pp_pred);
1171 } else {
1172 args.push(pp_obj_term);
1173 }
1174 } else {
1175 let event_sym = self.get_event_var();
1176 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1177 name: prep_name,
1178 args: self
1179 .ctx
1180 .terms
1181 .alloc_slice([Term::Variable(event_sym), pp_obj_term]),
1182 world: None,
1183 });
1184 pp_predicates.push(pp_pred);
1185 }
1186 }
1187
1188 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
1189 self.advance();
1190 let rel_var = self.next_var_name();
1191 let rel_pred = self.parse_relative_clause(rel_var)?;
1192 pp_predicates.push(rel_pred);
1193 }
1194
1195 let mut modifiers = self.collect_adverbs();
1196
1197 let effective_time = self.pending_time.take().unwrap_or(verb_time);
1198 match effective_time {
1199 Time::Past => modifiers.push(self.interner.intern("Past")),
1200 Time::Future => modifiers.push(self.interner.intern("Future")),
1201 _ => {}
1202 }
1203
1204 if verb_aspect == Aspect::Progressive {
1205 modifiers.push(self.interner.intern("Progressive"));
1206 } else if verb_aspect == Aspect::Perfect {
1207 modifiers.push(self.interner.intern("Perfect"));
1208 }
1209
1210 let mut roles: Vec<(ThematicRole, Term<'a>)> = Vec::new();
1211
1212 let verb_str = self.interner.resolve(verb).to_lowercase();
1214 let is_unaccusative = crate::lexicon::lookup_verb_db(&verb_str)
1215 .map(|meta| meta.features.contains(&crate::lexicon::Feature::Unaccusative))
1216 .unwrap_or(false);
1217
1218 let has_object = object_term.is_some() || second_object_term.is_some();
1221 let subject_role = if is_unaccusative && !has_object {
1222 ThematicRole::Theme
1223 } else {
1224 ThematicRole::Agent
1225 };
1226
1227 roles.push((subject_role, subject_term));
1228 if let Some(second_obj) = second_object_term {
1229 if let Some(first_obj) = object_term {
1230 roles.push((ThematicRole::Recipient, first_obj));
1231 }
1232 roles.push((ThematicRole::Theme, second_obj));
1233 } else if let Some(obj) = object_term {
1234 roles.push((ThematicRole::Theme, obj));
1235 }
1236
1237 let event_var = self.get_event_var();
1238 let suppress_existential = self.drs.in_conditional_antecedent();
1239 if suppress_existential {
1240 let event_class = self.interner.intern("Event");
1241 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
1242 }
1243 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
1244 event_var,
1245 verb,
1246 roles: self.ctx.roles.alloc_slice(roles.clone()),
1247 modifiers: self.ctx.syms.alloc_slice(modifiers.clone()),
1248 suppress_existential,
1249 world: None,
1250 })));
1251
1252 self.capture_event_template(verb, &roles, &modifiers);
1254
1255 let with_pps = if pp_predicates.is_empty() {
1256 neo_event
1257 } else {
1258 let mut combined = neo_event;
1259 for pp in pp_predicates {
1260 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1261 left: combined,
1262 op: TokenType::And,
1263 right: pp,
1264 });
1265 }
1266 combined
1267 };
1268
1269 let with_object_pps = if object_pps.is_empty() {
1272 with_pps
1273 } else if let Some(obj_term) = object_term {
1274 let placeholder = self.interner.intern("_PP_SELF_");
1275 let mut combined = with_pps;
1276 for pp in object_pps {
1277 let substituted = match pp {
1279 LogicExpr::Predicate { name, args, .. } => {
1280 let new_args: Vec<Term<'a>> = args
1281 .iter()
1282 .map(|arg| match arg {
1283 Term::Variable(v) if *v == placeholder => obj_term,
1284 other => *other,
1285 })
1286 .collect();
1287 self.ctx.exprs.alloc(LogicExpr::Predicate {
1288 name: *name,
1289 args: self.ctx.terms.alloc_slice(new_args),
1290 world: None,
1291 })
1292 }
1293 _ => *pp,
1294 };
1295 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1296 left: combined,
1297 op: TokenType::And,
1298 right: substituted,
1299 });
1300 }
1301 combined
1302 } else {
1303 with_pps
1304 };
1305
1306 let with_aspect = if verb_aspect == Aspect::Simple && effective_time == Time::Present {
1308 if !verb_class.is_stative() {
1310 self.ctx.exprs.alloc(LogicExpr::Aspectual {
1311 operator: AspectOperator::Habitual,
1312 body: with_object_pps,
1313 })
1314 } else {
1315 with_object_pps
1316 }
1317 } else if verb_aspect == Aspect::Progressive {
1318 if verb_class == crate::lexicon::VerbClass::Semelfactive {
1320 self.ctx.exprs.alloc(LogicExpr::Aspectual {
1321 operator: AspectOperator::Iterative,
1322 body: with_object_pps,
1323 })
1324 } else {
1325 with_object_pps
1326 }
1327 } else {
1328 with_object_pps
1329 };
1330
1331 Ok(with_aspect)
1332 } else {
1333 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject_symbol)))
1334 }
1335 }
1336}
1337
1338impl<'a, 'ctx, 'int> LogicVerbParsing<'a, 'ctx, 'int> for Parser<'a, 'ctx, 'int> {
1339 fn parse_predicate_with_subject(&mut self, subject_symbol: Symbol) -> ParseResult<&'a LogicExpr<'a>> {
1340 self.parse_predicate_impl(subject_symbol, false)
1341 }
1342
1343 fn parse_predicate_with_subject_as_var(&mut self, subject_symbol: Symbol) -> ParseResult<&'a LogicExpr<'a>> {
1344 self.parse_predicate_impl(subject_symbol, true)
1345 }
1346
1347 fn try_parse_plural_subject(
1348 &mut self,
1349 first_subject: &NounPhrase<'a>,
1350 ) -> Result<Option<&'a LogicExpr<'a>>, ParseError> {
1351 let saved_pos = self.current;
1352
1353 self.advance();
1355
1356 if !self.check_content_word() {
1357 self.current = saved_pos;
1358 return Ok(None);
1359 }
1360
1361 let mut subjects: Vec<Symbol> = vec![first_subject.noun];
1363
1364 loop {
1365 if !self.check_content_word() {
1366 break;
1367 }
1368 let next_subject = match self.parse_noun_phrase(true) {
1369 Ok(np) => np,
1370 Err(_) => {
1371 self.current = saved_pos;
1372 return Ok(None);
1373 }
1374 };
1375 subjects.push(next_subject.noun);
1376
1377 if self.check(&TokenType::And) {
1378 self.advance();
1379 } else {
1380 break;
1381 }
1382 }
1383
1384 if self.check(&TokenType::Is) || self.check(&TokenType::Are)
1387 || self.check(&TokenType::Was) || self.check(&TokenType::Were)
1388 {
1389 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
1390 Time::Past
1391 } else {
1392 Time::Present
1393 };
1394 self.advance(); if !self.check_content_word() && !self.check_article() {
1398 self.current = saved_pos;
1399 return Ok(None);
1400 }
1401
1402 let predicate_np = match self.parse_noun_phrase(false) {
1403 Ok(np) => np,
1404 Err(_) => {
1405 self.current = saved_pos;
1406 return Ok(None);
1407 }
1408 };
1409 let predicate = predicate_np.noun;
1410
1411 let mut conjuncts: Vec<&'a LogicExpr<'a>> = Vec::new();
1413 for subj in &subjects {
1414 let pred_expr = self.ctx.exprs.alloc(LogicExpr::Predicate {
1415 name: predicate,
1416 args: self.ctx.terms.alloc_slice([Term::Constant(*subj)]),
1417 world: None,
1418 });
1419 conjuncts.push(pred_expr);
1420 }
1421
1422 let mut result = conjuncts[0];
1424 for conjunct in &conjuncts[1..] {
1425 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1426 left: result,
1427 op: TokenType::And,
1428 right: *conjunct,
1429 });
1430 }
1431
1432 let with_time = match copula_time {
1434 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1435 operator: TemporalOperator::Past,
1436 body: result,
1437 }),
1438 _ => result,
1439 };
1440
1441 return Ok(Some(with_time));
1442 }
1443
1444 if !self.check_verb() {
1445 self.current = saved_pos;
1446 return Ok(None);
1447 }
1448
1449 let (verb, verb_time, _verb_aspect, _) = self.consume_verb_with_metadata();
1452
1453 if self.check(&TokenType::Reciprocal) {
1455 self.advance();
1456 if subjects.len() != 2 {
1457 self.current = saved_pos;
1458 return Ok(None);
1459 }
1460 let pred1 = self.ctx.exprs.alloc(LogicExpr::Predicate {
1461 name: verb,
1462 args: self.ctx.terms.alloc_slice([
1463 Term::Constant(subjects[0]),
1464 Term::Constant(subjects[1]),
1465 ]),
1466 world: None,
1467 });
1468 let pred2 = self.ctx.exprs.alloc(LogicExpr::Predicate {
1469 name: verb,
1470 args: self.ctx.terms.alloc_slice([
1471 Term::Constant(subjects[1]),
1472 Term::Constant(subjects[0]),
1473 ]),
1474 world: None,
1475 });
1476 let expr = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1477 left: pred1,
1478 op: TokenType::And,
1479 right: pred2,
1480 });
1481
1482 let with_time = match verb_time {
1483 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1484 operator: TemporalOperator::Past,
1485 body: expr,
1486 }),
1487 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1488 operator: TemporalOperator::Future,
1489 body: expr,
1490 }),
1491 _ => expr,
1492 };
1493 return Ok(Some(with_time));
1494 }
1495
1496 let mut objects: Vec<Symbol> = Vec::new();
1498 if self.check_content_word() || self.check_article() {
1499 let first_obj = match self.parse_noun_phrase(false) {
1501 Ok(np) => np,
1502 Err(_) => {
1503 return Ok(Some(self.build_group_predicate(&subjects, verb, verb_time)));
1505 }
1506 };
1507 objects.push(first_obj.noun);
1508
1509 while self.check(&TokenType::And) {
1511 self.advance();
1512 if self.check_content_word() || self.check_article() {
1513 let next_obj = match self.parse_noun_phrase(false) {
1514 Ok(np) => np,
1515 Err(_) => break,
1516 };
1517 objects.push(next_obj.noun);
1518 } else {
1519 break;
1520 }
1521 }
1522 }
1523
1524 if self.check(&TokenType::Respectively) {
1526 let respectively_span = self.peek().span;
1527 self.advance(); if subjects.len() != objects.len() {
1530 return Err(ParseError {
1531 kind: ParseErrorKind::RespectivelyLengthMismatch {
1532 subject_count: subjects.len(),
1533 object_count: objects.len(),
1534 },
1535 span: respectively_span,
1536 });
1537 }
1538
1539 let mut conjuncts: Vec<&'a LogicExpr<'a>> = Vec::new();
1541 let suppress_existential = self.drs.in_conditional_antecedent();
1542 for (subj, obj) in subjects.iter().zip(objects.iter()) {
1543 let event_var = self.get_event_var();
1544 let roles = vec![
1545 (ThematicRole::Agent, Term::Constant(*subj)),
1546 (ThematicRole::Theme, Term::Constant(*obj)),
1547 ];
1548 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
1549 event_var,
1550 verb,
1551 roles: self.ctx.roles.alloc_slice(roles),
1552 modifiers: self.ctx.syms.alloc_slice(vec![]),
1553 suppress_existential,
1554 world: None,
1555 })));
1556 conjuncts.push(neo_event);
1557 }
1558
1559 let mut result = conjuncts[0];
1561 for conjunct in &conjuncts[1..] {
1562 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1563 left: result,
1564 op: TokenType::And,
1565 right: *conjunct,
1566 });
1567 }
1568
1569 let with_time = match verb_time {
1571 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1572 operator: TemporalOperator::Past,
1573 body: result,
1574 }),
1575 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1576 operator: TemporalOperator::Future,
1577 body: result,
1578 }),
1579 _ => result,
1580 };
1581
1582 return Ok(Some(with_time));
1583 }
1584
1585 if objects.is_empty() {
1587 Ok(Some(self.build_group_predicate(&subjects, verb, verb_time)))
1589 } else {
1590 Ok(Some(self.build_group_transitive(&subjects, &objects, verb, verb_time)))
1592 }
1593 }
1594
1595 fn build_group_predicate(
1597 &mut self,
1598 subjects: &[Symbol],
1599 verb: Symbol,
1600 verb_time: Time,
1601 ) -> &'a LogicExpr<'a> {
1602 let group_members: Vec<Term<'a>> = subjects.iter()
1603 .map(|s| Term::Constant(*s))
1604 .collect();
1605 let group_members_slice = self.ctx.terms.alloc_slice(group_members);
1606
1607 let expr = self.ctx.exprs.alloc(LogicExpr::Predicate {
1608 name: verb,
1609 args: self.ctx.terms.alloc_slice([Term::Group(group_members_slice)]),
1610 world: None,
1611 });
1612
1613 match verb_time {
1614 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1615 operator: TemporalOperator::Past,
1616 body: expr,
1617 }),
1618 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1619 operator: TemporalOperator::Future,
1620 body: expr,
1621 }),
1622 _ => expr,
1623 }
1624 }
1625
1626 fn build_group_transitive(
1628 &mut self,
1629 subjects: &[Symbol],
1630 objects: &[Symbol],
1631 verb: Symbol,
1632 verb_time: Time,
1633 ) -> &'a LogicExpr<'a> {
1634 let subj_members: Vec<Term<'a>> = subjects.iter()
1635 .map(|s| Term::Constant(*s))
1636 .collect();
1637 let obj_members: Vec<Term<'a>> = objects.iter()
1638 .map(|o| Term::Constant(*o))
1639 .collect();
1640
1641 let subj_group = Term::Group(self.ctx.terms.alloc_slice(subj_members));
1642 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
1643
1644 let expr = self.ctx.exprs.alloc(LogicExpr::Predicate {
1645 name: verb,
1646 args: self.ctx.terms.alloc_slice([subj_group, obj_group]),
1647 world: None,
1648 });
1649
1650 match verb_time {
1651 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1652 operator: TemporalOperator::Past,
1653 body: expr,
1654 }),
1655 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1656 operator: TemporalOperator::Future,
1657 body: expr,
1658 }),
1659 _ => expr,
1660 }
1661 }
1662
1663 fn parse_control_structure(
1664 &mut self,
1665 subject: &NounPhrase<'a>,
1666 verb: Symbol,
1667 verb_time: Time,
1668 ) -> ParseResult<&'a LogicExpr<'a>> {
1669 let subject_sym = subject.noun;
1670 let verb_str = self.interner.resolve(verb);
1671
1672 if Lexer::is_raising_verb(verb_str) {
1673 if !self.check_to() {
1674 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
1675 name: verb,
1676 args: self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1677 world: None,
1678 }));
1679 }
1680 self.advance();
1681
1682 if !self.check_verb() {
1683 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
1684 name: verb,
1685 args: self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1686 world: None,
1687 }));
1688 }
1689
1690 let inf_verb = self.consume_verb();
1691
1692 let embedded = if self.is_control_verb(inf_verb) {
1693 let raised_np = NounPhrase {
1694 noun: subject_sym,
1695 definiteness: None,
1696 adjectives: &[],
1697 possessor: None,
1698 pps: &[],
1699 superlative: None,
1700 };
1701 self.parse_control_structure(&raised_np, inf_verb, Time::None)?
1702 } else {
1703 self.ctx.exprs.alloc(LogicExpr::Predicate {
1704 name: inf_verb,
1705 args: self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1706 world: None,
1707 })
1708 };
1709
1710 let result = self.ctx.exprs.alloc(LogicExpr::Scopal {
1711 operator: verb,
1712 body: embedded,
1713 });
1714
1715 return Ok(match verb_time {
1716 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1717 operator: TemporalOperator::Past,
1718 body: result,
1719 }),
1720 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1721 operator: TemporalOperator::Future,
1722 body: result,
1723 }),
1724 _ => result,
1725 });
1726 }
1727
1728 let is_object_control = Lexer::is_object_control_verb(self.interner.resolve(verb));
1729 let (object_term, pro_controller_sym) = if self.check_to() {
1730 (None, subject_sym)
1731 } else if self.check_content_word() {
1732 let object_np = self.parse_noun_phrase(false)?;
1733 let obj_sym = object_np.noun;
1734
1735 let controller = if is_object_control {
1736 obj_sym
1737 } else {
1738 subject_sym
1739 };
1740 (
1741 Some(self.ctx.terms.alloc(Term::Constant(obj_sym))),
1742 controller,
1743 )
1744 } else {
1745 (None, subject_sym)
1746 };
1747
1748 if !self.check_to() {
1749 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
1750 name: verb,
1751 args: match object_term {
1752 Some(obj) => self.ctx.terms.alloc_slice([
1753 Term::Constant(subject_sym),
1754 Term::Constant(match obj {
1755 Term::Constant(s) => *s,
1756 _ => subject_sym,
1757 }),
1758 ]),
1759 None => self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1760 },
1761 world: None,
1762 }));
1763 }
1764 self.advance();
1765
1766 if !self.check_verb() {
1767 return Ok(self.ctx.exprs.alloc(LogicExpr::Predicate {
1768 name: verb,
1769 args: self.ctx.terms.alloc_slice([Term::Constant(subject_sym)]),
1770 world: None,
1771 }));
1772 }
1773
1774 let inf_verb = self.consume_verb();
1775 let inf_verb_str = self.interner.resolve(inf_verb).to_lowercase();
1776
1777 let infinitive = if inf_verb_str == "be" && self.check_verb() {
1778 let passive_verb = self.consume_verb();
1779 let passive_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
1780 name: passive_verb,
1781 args: self
1782 .ctx
1783 .terms
1784 .alloc_slice([Term::Constant(pro_controller_sym)]),
1785 world: None,
1786 });
1787 self.ctx.voice(crate::ast::VoiceOperator::Passive, passive_pred)
1788 } else if self.is_control_verb(inf_verb) {
1789 let controller_np = NounPhrase {
1790 noun: pro_controller_sym,
1791 definiteness: None,
1792 adjectives: &[],
1793 possessor: None,
1794 pps: &[],
1795 superlative: None,
1796 };
1797 self.parse_control_structure(&controller_np, inf_verb, Time::None)?
1798 } else {
1799 self.ctx.exprs.alloc(LogicExpr::Predicate {
1800 name: inf_verb,
1801 args: self
1802 .ctx
1803 .terms
1804 .alloc_slice([Term::Constant(pro_controller_sym)]),
1805 world: None,
1806 })
1807 };
1808
1809 let control = self.ctx.exprs.alloc(LogicExpr::Control {
1810 verb,
1811 subject: self.ctx.terms.alloc(Term::Constant(subject_sym)),
1812 object: object_term,
1813 infinitive,
1814 });
1815
1816 Ok(match verb_time {
1817 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
1818 operator: TemporalOperator::Past,
1819 body: control,
1820 }),
1821 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
1822 operator: TemporalOperator::Future,
1823 body: control,
1824 }),
1825 _ => control,
1826 })
1827 }
1828
1829 fn is_control_verb(&self, verb: Symbol) -> bool {
1830 let lemma = self.interner.resolve(verb);
1831 Lexer::is_subject_control_verb(lemma)
1832 || Lexer::is_object_control_verb(lemma)
1833 || Lexer::is_raising_verb(lemma)
1834 }
1835}