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)
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
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
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