| 655 | |
| 656 | |
| 657 | class AndExpectation(DerivativeExpectation): |
| 658 | OPERATOR = "&" |
| 659 | |
| 660 | def test(self, first, last): |
| 661 | assert isinstance(first, Occurrence) |
| 662 | assert isinstance(last, Occurrence) |
| 663 | |
| 664 | if len(self.expectations) <= 1: |
| 665 | for exp in self.expectations: |
| 666 | for reasons in exp.test(first, last): |
| 667 | yield reasons |
| 668 | return |
| 669 | |
| 670 | lhs = self.expectations[0] |
| 671 | rhs = AndExpectation(*self.expectations[1:]) |
| 672 | for lhs_reasons in lhs.test(first, last): |
| 673 | for rhs_reasons in rhs.test(first, last): |
| 674 | reasons = lhs_reasons.copy() |
| 675 | reasons.update(rhs_reasons) |
| 676 | yield reasons |
| 677 | |
| 678 | @property |
| 679 | def has_lower_bound(self): |
| 680 | return any(exp.has_lower_bound for exp in self.expectations) |
| 681 | |
| 682 | def __and__(self, other): |
| 683 | assert isinstance(other, Expectation) |
| 684 | return AndExpectation(*(self.expectations + (other,))) |
| 685 | |
| 686 | def __repr__(self): |
| 687 | return "(" + " & ".join(repr(exp) for exp in self.expectations) + ")" |
| 688 | |
| 689 | |
| 690 | class XorExpectation(DerivativeExpectation): |