def agreement(self, predication, world):
        if self.qtype == 'composed':
            quantifiers = [Quantifier(qtype=quantifier[0], qrange=quantifier[1], quantity=quantifier[2], restrictor=self.restrictor, comparison=self.comparison, body=self.body) for quantifier in self.quantity]
            return min(quantifier.agreement(predication=predication.copy(include_sub_predications=True), world=world) for quantifier in quantifiers)

        rstr_predication = predication.get_sub_predication()
        rstr_body_predication = predication.get_sub_predication()
        assert rstr_body_predication <= rstr_predication

        comp_predication = predication.get_sub_predication()
        comp_body_predication = predication.get_sub_predication()
        assert comp_body_predication <= comp_predication

        if self.qtype == 'count':
            lower = rstr_body_predication.num_agreeing - comp_body_predication.num_not_disagreeing
            upper = rstr_body_predication.num_not_disagreeing - comp_body_predication.num_agreeing

        elif self.qtype == 'ratio':
            if comp_body_predication.num_not_disagreeing == 0:
                if rstr_body_predication.num_agreeing == 0:
                    lower = 0.0
                else:
                    lower = float('inf')
            else:
                lower = rstr_body_predication.num_agreeing / comp_body_predication.num_not_disagreeing
            if comp_body_predication.num_agreeing == 0:
                if rstr_body_predication.num_not_disagreeing == 0:
                    upper = 0.0
                else:
                    upper = float('inf')
            else:
                upper = rstr_body_predication.num_not_disagreeing / comp_body_predication.num_agreeing

        return Quantifier.get_agreement(qrange=self.qrange, lower=lower, upper=upper, target=self.quantity)
    def agreement(self, predication, world):
        rstr_predication = predication.get_sub_predication(0)
        rstr_body_predication = predication.get_sub_predication(1)
        assert rstr_body_predication <= rstr_predication

        comp_predication = predication.get_sub_predication(2)
        comp_body_predication = predication.get_sub_predication(3)
        assert comp_body_predication <= comp_predication

        if self.qtype == 'count':
            lower = rstr_body_predication.num_agreeing - comp_body_predication.num_not_disagreeing
            upper = rstr_body_predication.num_not_disagreeing - comp_body_predication.num_agreeing

        elif self.qtype == 'ratio':
            if comp_body_predication.num_not_disagreeing == 0:
                if rstr_body_predication.num_agreeing == 0:
                    lower = 0.0
                else:
                    lower = float('inf')
            else:
                lower = rstr_body_predication.num_agreeing / comp_body_predication.num_not_disagreeing
            if comp_body_predication.num_agreeing == 0:
                if rstr_body_predication.num_not_disagreeing == 0:
                    upper = 0.0
                else:
                    upper = float('inf')
            else:
                upper = rstr_body_predication.num_not_disagreeing / comp_body_predication.num_agreeing

        return Quantifier.get_agreement(qrange=self.qrange,
                                        lower=lower,
                                        upper=upper,
                                        target=self.quantity)
Example #3
0
    def set_realizer(self, realizer):
        if not super(ComparativeQuantifierCaptioner,
                     self).set_realizer(realizer):
            return False

        if self.comparative_quantifiers is None:
            self.comparative_quantifiers = [
                (qtype, qrange, quantity)
                for qtype, qranges in realizer.comparative_quantifiers.items()
                for qrange, quantities in qranges.items()
                for quantity in quantities
            ]
        else:
            self.comparative_quantifiers = Quantifier.filter(
                quantifiers=((qtype, qrange, quantity) for qtype, qranges in
                             realizer.comparative_quantifiers.items()
                             for qrange, quantities in qranges.items()
                             for quantity in quantities),
                selection=self.comparative_quantifiers)

        self.comparative_quantifiers = {
            qtype_key:
            [(qrange, quantity)
             for qtype, qrange, quantity in self.comparative_quantifiers
             if qtype == qtype_key]
            for qtype_key, _, _ in self.comparative_quantifiers
        }

        return True
Example #4
0
    def caption(self, predication, world):
        assert predication.empty()

        rstr_predication = predication.sub_predication()
        body_predication = predication.sub_predication()
        rstr_body_predication = predication.sub_predication()

        if (self.qtype, self.qrange,
                self.quantity) in Quantifier.zero_quantifiers:
            # special case: zero quantifier, hence incorrect body
            rstr_body_predication_copy = rstr_body_predication.copy()
            body = self.body_captioner.caption(
                predication=rstr_body_predication_copy, world=world)
            if body is None:
                return None
            if not self.body_captioner.incorrect(
                    caption=body, predication=rstr_body_predication,
                    world=world):
                return None

            restrictor = self.restrictor_captioner.caption(
                predication=rstr_body_predication_copy, world=world)
            if restrictor is None:
                return None
            restrictor.apply_to_predication(predication=rstr_body_predication)

        else:
            body = self.body_captioner.caption(
                predication=rstr_body_predication, world=world)
            if body is None:
                return None

            restrictor = self.restrictor_captioner.caption(
                predication=rstr_body_predication, world=world)
            if restrictor is None:
                return None

        restrictor.apply_to_predication(predication=rstr_predication)
        body.apply_to_predication(predication=body_predication)

        if self.quantity < 0 and -(self.quantity +
                                   1) > rstr_predication.num_agreeing:
            return None

        if not self.pragmatical_tautology and (
                self.qtype, self.qrange, self.quantity
        ) not in Quantifier.all_quantifiers and rstr_predication.equals(
                other=body_predication):
            # all quantification is inherently tautological
            return None

        return Quantifier(qtype=self.qtype,
                          qrange=self.qrange,
                          quantity=self.quantity,
                          restrictor=restrictor,
                          body=body)
    def set_realizer(self, realizer):
        if not super(QuantifierCaptioner, self).set_realizer(realizer):
            return False

        if self.quantifiers is None:
            self.quantifiers = [
                (qtype, qrange, quantity)
                for qtype, qranges in realizer.quantifiers.items()
                for qrange, quantities in qranges.items()
                for quantity in quantities
            ]
        else:
            self.quantifiers = Quantifier.filter(quantifiers=(
                (qtype, qrange, quantity)
                for qtype, qranges in realizer.quantifiers.items()
                for qrange, quantities in qranges.items()
                for quantity in quantities),
                                                 selection=self.quantifiers)

        self.zero_quantifiers = set(
            Quantifier.filter(quantifiers=self.quantifiers,
                              selection=Quantifier.zero_quantifiers))
        self.zero_included_quantifiers = set(
            Quantifier.filter(quantifiers=self.quantifiers,
                              selection=Quantifier.zero_included_quantifiers))
        self.zero_negated_quantifiers = set(
            Quantifier.filter(quantifiers=self.quantifiers,
                              selection=Quantifier.zero_negated_quantifiers))
        self.all_quantifiers = set(
            Quantifier.filter(quantifiers=self.quantifiers,
                              selection=Quantifier.all_quantifiers))
        self.all_included_quantifiers = set(
            Quantifier.filter(quantifiers=self.quantifiers,
                              selection=Quantifier.all_included_quantifiers))
        self.all_negated_quantifiers = set(
            Quantifier.filter(quantifiers=self.quantifiers,
                              selection=Quantifier.all_negated_quantifiers))
        self.tautological_quantifiers = set(
            Quantifier.filter(quantifiers=self.quantifiers,
                              selection=Quantifier.tautological_quantifiers))
        self.quantifiers = {
            qtype_key: [(qrange, quantity)
                        for qtype, qrange, quantity in self.quantifiers
                        if qtype == qtype_key]
            for qtype_key, _, _ in self.quantifiers
        }

        return True
    def caption(self, predication, world):
        assert predication.empty()

        rstr_body_predication = predication.copy()
        if self.zero_quantification:
            # special case: zero quantifier, hence incorrect body
            body = self.body_captioner.caption(
                predication=rstr_body_predication, world=world)
            if body is None:
                return None

            restrictor = self.restrictor_captioner.caption(
                predication=rstr_body_predication, world=world)
            if restrictor is None:
                return None

            body_predication = predication.copy()
            if not self.body_captioner.incorrect(
                    caption=body, predication=body_predication, world=world):
                return None

        else:
            body = self.body_captioner.caption(
                predication=rstr_body_predication, world=world)
            if body is None:
                return None

            restrictor = self.restrictor_captioner.caption(
                predication=rstr_body_predication, world=world)
            if restrictor is None:
                return None

        # also for incorrect
        # if not self.pragmatical_tautology and not self.all_quantification and len(rstr_body_predication.agreeing) > 1 and (body_predication.equals(other=rstr_body_predication) or rstr_predication.equals(other=rstr_body_predication)):
        #     # all quantification is inherently tautological
        #     return None

        quantifier = Quantifier(qtype=self.qtype,
                                qrange=self.qrange,
                                quantity=self.quantity,
                                restrictor=restrictor,
                                body=body)

        if not self.correct(caption=quantifier, predication=predication):
            return None

        return quantifier
    def sample_values(self, mode, predication):
        assert predication.empty()

        if not super(QuantifierCaptioner, self).sample_values(
                mode=mode, predication=predication):
            return False

        # predication = predication.copy()

        if not self.body_captioner.sample_values(mode=mode,
                                                 predication=predication):
            return False
        if not self.restrictor_captioner.sample_values(
                mode=mode, predication=predication):
            return False

        self.qtype = choice(list(self.quantifiers))
        self.qrange, self.quantity = choice(self.quantifiers[self.qtype])

        if (self.qtype, self.qrange, self.quantity) in self.zero_quantifiers:
            assert self.body_captioner.incorrect_possible()
            self.zero_quantification = True
        elif (self.qtype, self.qrange,
              self.quantity) in self.zero_included_quantifiers:
            self.zero_quantification = self.body_captioner.incorrect_possible(
            ) and random() < self.zero_quantification_rate
        else:
            self.zero_quantification = False

        if (self.qtype, self.qrange, self.quantity) in self.all_quantifiers:
            self.all_quantification = True
        elif (self.qtype, self.qrange,
              self.quantity) in self.all_included_quantifiers:
            self.all_quantification = random() < self.all_quantification_rate
        else:
            self.all_quantification = False

        for _ in range(self.__class__.MAX_SAMPLE_ATTEMPTS):
            self.incorrect_mode = util.sample(self.incorrect_distribution)
            if self.incorrect_mode == 0 and not self.restrictor_captioner.incorrect_possible(
            ):
                continue
            elif self.incorrect_mode == 1 and not self.body_captioner.incorrect_possible(
            ):
                continue
            elif self.incorrect_mode == 0 and self.zero_quantification:
                continue
            elif self.incorrect_mode in (
                    0, 1) and (self.qtype, self.qrange,
                               self.quantity) in self.tautological_quantifiers:
                # always true in whatever way restrictor/body is changed
                continue
            elif self.incorrect_mode == 3 and not any(
                    q == self.quantity and r != self.qrange
                    for r, q in self.quantifiers[self.qtype]):
                continue
            elif self.incorrect_mode == 4 and not any(
                    r == self.qrange and q != self.quantity
                    for r, q in self.quantifiers[self.qtype]):
                continue
            break
        else:
            return False

        if self.incorrect_mode < 2:
            self.incorrect_qrange = self.qrange
            self.incorrect_quantity = self.quantity

        else:  # incorrect quantifier
            if self.incorrect_mode == 2:
                closest_quantities = list()
            for _ in range(self.__class__.MAX_SAMPLE_ATTEMPTS):

                if self.incorrect_mode == 2:  # 2: closest quantity
                    self.incorrect_qrange = self.qrange
                    self.incorrect_quantity = None
                    if self.qrange in ('lt',
                                       'leq') or (self.qrange in ('eq', 'neq')
                                                  and random() < 0.5):
                        for r, q in self.quantifiers[self.qtype]:
                            if r != self.qrange:
                                continue
                            elif self.qtype == 'ratio' and q >= self.quantity:
                                continue
                            elif self.qtype == 'count' and (
                                    q + 1000 *
                                (q < 0) >= self.quantity + 1000 *
                                (self.quantity < 0)):
                                continue
                            elif q in closest_quantities:
                                continue
                            elif self.incorrect_quantity is None or q > self.incorrect_quantity:
                                self.incorrect_quantity = q
                    else:
                        for r, q in self.quantifiers[self.qtype]:
                            if r != self.qrange:
                                continue
                            elif self.qtype == 'ratio' and q <= self.quantity:
                                continue
                            elif self.qtype == 'count' and (
                                    q + 1000 *
                                (q < 0) <= self.quantity + 1000 *
                                (self.quantity < 0)):
                                continue
                            elif q in closest_quantities:
                                continue
                            elif self.incorrect_quantity is None or q < self.incorrect_quantity:
                                self.incorrect_quantity = q
                    if self.incorrect_quantity is None:
                        return False
                    closest_quantities.append(self.incorrect_quantity)
                if self.incorrect_mode == 3:  # 3: incorrect range
                    self.incorrect_qrange = choice([
                        r for r, q in self.quantifiers[self.qtype]
                        if q == self.quantity and r != self.qrange
                    ])
                    self.incorrect_quantity = self.quantity
                elif self.incorrect_mode == 4:  # 4: incorrect quantity
                    self.incorrect_qrange = self.qrange
                    self.incorrect_quantity = choice([
                        q for r, q in self.quantifiers[self.qtype]
                        if r == self.qrange and q != self.quantity
                    ])
                elif self.incorrect_mode == 5:  # 5: incorrect quantifier of same type
                    self.incorrect_qrange, self.incorrect_quantity = choice(
                        self.quantifiers[self.qtype])

                if Quantifier.tautological(qtype=self.qtype,
                                           qrange1=self.qrange,
                                           quantity1=self.quantity,
                                           qrange2=self.incorrect_qrange,
                                           quantity2=self.incorrect_quantity):
                    continue
                elif (self.qtype, self.incorrect_qrange,
                      self.incorrect_quantity
                      ) in self.tautological_quantifiers:
                    # always true, so never incorrect
                    continue
                elif self.zero_quantification and (
                        self.qtype, self.incorrect_qrange, self.
                        incorrect_quantity) in self.zero_included_quantifiers:
                    # always true if zero, so never incorrect
                    continue
                elif not self.zero_quantification and (
                        self.qtype, self.incorrect_qrange,
                        self.incorrect_quantity
                ) in Quantifier.zero_negated_quantifiers:
                    # always true unless zero, so never incorrect
                    continue
                elif self.all_quantification and (
                        self.qtype, self.incorrect_qrange, self.
                        incorrect_quantity) in self.all_included_quantifiers:
                    # always true if all, so never incorrect
                    continue
                elif not self.all_quantification and (
                        self.qtype, self.incorrect_qrange, self.
                        incorrect_quantity) in self.all_negated_quantifiers:
                    # always true unless all, so never incorrect
                    continue
                break

            else:
                return False

        return True
Example #8
0
    def sample_values(self, mode, predication):
        assert predication.empty()

        if not super(ComparativeQuantifierCaptioner, self).sample_values(
                mode=mode, predication=predication):
            return False

        # predication = predication.copy()

        if not self.body_captioner.sample_values(mode=mode,
                                                 predication=predication):
            return False
        if not self.restrictor_captioner.sample_values(
                mode=mode, predication=predication.copy()):
            return False
        if not self.comparison_captioner.sample_values(
                mode=mode, predication=predication.copy()):
            return False

        # rstr_predication = predication.copy()
        # comp_predication = predication.copy()
        # if not self.restrictor_captioner.sample_values(mode=mode, predication=rstr_predication):
        #     return False
        # if not self.comparison_captioner.sample_values(mode=mode, predication=comp_predication):
        #     return False
        # union_predication = rstr_predication.union(other=comp_predication)
        # if self.body_captioner.sample_values(mode=mode, predication=union_predication):
        #     break

        self.qtype = choice(list(self.comparative_quantifiers))
        self.qrange, self.quantity = choice(
            self.comparative_quantifiers[self.qtype])

        for _ in range(self.__class__.MAX_SAMPLE_ATTEMPTS):
            self.incorrect_mode = util.sample(self.incorrect_distribution)
            if self.incorrect_mode == 0 and not self.restrictor_captioner.incorrect_possible(
            ):
                continue
            elif self.incorrect_mode == 1 and not self.comparison_captioner.incorrect_possible(
            ):
                continue
            elif self.incorrect_mode == 2 and not self.body_captioner.incorrect_possible(
            ):
                continue
            elif self.incorrect_mode == 4 and not any(
                    q == self.quantity and r != self.qrange
                    for r, q in self.comparative_quantifiers[self.qtype]):
                continue
            elif self.incorrect_mode == 5 and not any(
                    r == self.qrange and q != self.quantity
                    for r, q in self.comparative_quantifiers[self.qtype]):
                continue
            else:
                break
        else:
            return False

        if self.incorrect_mode >= 3:  # incorrect quantifier
            if self.incorrect_mode == 3:
                closest_quantities = list()
            for _ in range(self.__class__.MAX_SAMPLE_ATTEMPTS):

                if self.incorrect_mode == 3:  # 3: closest quantity
                    self.incorrect_qrange = self.qrange
                    self.incorrect_quantity = None
                    if self.qrange in ('lt',
                                       'leq') or (self.qrange in ('eq', 'neq')
                                                  and random() < 0.5):
                        for r, q in self.comparative_quantifiers[self.qtype]:
                            if r != self.qrange or q >= self.quantity:
                                continue
                            elif q in closest_quantities:
                                continue
                            elif self.incorrect_quantity is None or q > self.incorrect_quantity:
                                self.incorrect_quantity = q
                    else:
                        for r, q in self.comparative_quantifiers[self.qtype]:
                            if r != self.qrange or q <= self.quantity:
                                continue
                            elif q in closest_quantities:
                                continue
                            elif self.incorrect_quantity is None or q < self.incorrect_quantity:
                                self.incorrect_quantity = q
                    if self.incorrect_quantity is None:
                        return False
                    closest_quantities.append(self.incorrect_quantity)
                if self.incorrect_mode == 4:  # 4: incorrect range
                    self.incorrect_qrange = choice([
                        r for r, q in self.comparative_quantifiers[self.qtype]
                        if q == self.quantity and r != self.qrange
                    ])
                    self.incorrect_quantity = self.quantity
                elif self.incorrect_mode == 5:  # 5: incorrect quantity
                    self.incorrect_qrange = self.qrange
                    self.incorrect_quantity = choice([
                        q for r, q in self.comparative_quantifiers[self.qtype]
                        if r == self.qrange and q != self.quantity
                    ])
                elif self.incorrect_mode == 6:  # 6: incorrect quantifier of same type
                    self.incorrect_qrange, self.incorrect_quantity = choice(
                        self.comparative_quantifiers[self.qtype])

                if Quantifier.tautological(qtype=self.qtype,
                                           qrange1=self.qrange,
                                           quantity1=self.quantity,
                                           qrange2=self.incorrect_qrange,
                                           quantity2=self.incorrect_quantity):
                    continue
                break

            else:
                return False

        return True