When a measurement adjective like "tall" is defined, so is a comparative relation like "taller than".
§1. Family. There can be many of these. Each is associated with a property, but some properties may never be measured ("carrying capacity", say) while others may have more than one comparative (a property such as "height" might have relations for both "shorter" and "taller"). So comparative relations do not correspond exactly with properties.
Global knowledge variable definitions3 +=
bp_family *property_comparison_bp_family = NULL;
- This code is a continuation of 1/km:§3.
void ComparativeRelations::start(void) { property_comparison_bp_family = BinaryPredicateFamilies::new(); METHOD_ADD(property_comparison_bp_family, STOCK_BPF_MTID, ComparativeRelations::stock); METHOD_ADD(property_comparison_bp_family, TYPECHECK_BPF_MTID, ComparativeRelations::typecheck); METHOD_ADD(property_comparison_bp_family, SCHEMA_BPF_MTID, ComparativeRelations::schema); }
§3. Creation. When an adjective is defined so that it performs an inequality comparison of a property value, like so:
Definition: A woman is tall if her height is 68 or more.
...Inform automatically generates a comparative form (here "taller than"). This is where our comparative relations come from, but the work is done in Measurement Adjectives, not here.
void ComparativeRelations::stock(bp_family *self, int n) { if (n == 2) Measurements::create_comparatives(); }
§4. However, whenever a comparative is made, an instance of the following is created and attached to it:
classdef comparative_bp_data { struct property *comparative_property; /* (if right way) if a comparative adjective */ int comparison_sign; /* ...and+1or-1according to sign of definition */ } void ComparativeRelations::initialise(binary_predicate *bp, int sign, property *prn) { comparative_bp_data *D = CREATE(comparative_bp_data); D->comparison_sign = sign; D->comparative_property = prn; bp->family_specific = STORE_POINTER_comparative_bp_data(D); }
- The structure comparative_bp_data is private to this section.
§5. Typechecking. Comparatives can be used in two different senses, which we'll call absolute and relative:
- "if Geoff is taller than 4 foot 5 inches" is absolute, while
- "if Geoff is taller than Miranda" is relative.
This can be quite polymorphic, since different kinds can have the same property. We typecheck that the kind of the left term provides the property, and that the right term is either a value of the property, or an instance of a kind which also provides the property.
int ComparativeRelations::typecheck(bp_family *self, binary_predicate *bp, pcalc_term *terms, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) { comparative_bp_data *D = RETRIEVE_POINTER_comparative_bp_data(bp->family_specific); if (Kinds::eq(K_object, Kinds::weaken(kinds_of_terms[0], K_object))) { if (PropertyPermissions::find_any_object(D->comparative_property) == NULL) { LOG("Term 0 is %u, a kind of object, no kind of which provides $Y)\n", kinds_of_terms[0], D->comparative_property); TypecheckPropositions::issue_bp_typecheck_error(bp, kinds_of_terms[0], kinds_of_terms[1], tck); return NEVER_MATCH; } } else { if (PropertyPermissions::find( KindSubjects::from_kind(kinds_of_terms[0]), D->comparative_property, TRUE) == NULL) { LOG("Term 0 is %u which does not provide $Y)\n", kinds_of_terms[0], D->comparative_property); TypecheckPropositions::issue_bp_typecheck_error(bp, kinds_of_terms[0], kinds_of_terms[1], tck); return NEVER_MATCH; } } if (Kinds::eq(Kinds::weaken(kinds_of_terms[0], K_object), Kinds::weaken(kinds_of_terms[1], K_object))) return ALWAYS_MATCH; kind *KV = ValueProperties::kind(D->comparative_property); if (Kinds::compatible(kinds_of_terms[1], KV) != NEVER_MATCH) return ALWAYS_MATCH; Problems::quote_kind(4, kinds_of_terms[1]); Problems::quote_kind(5, KV); StandardProblems::tcp_problem(_p_(PM_ComparativeMisapplied), tck, "that ought to make a comparison of %5 not %4."); return NEVER_MATCH; }
int ComparativeRelations::schema(bp_family *self, int task, binary_predicate *bp, annotated_i6_schema *asch) { comparative_bp_data *D = RETRIEVE_POINTER_comparative_bp_data(bp->family_specific); kind *st[2]; st[0] = Cinders::kind_of_term(asch->pt0); st[1] = Cinders::kind_of_term(asch->pt1); if (task == TEST_ATOM_TASK) { if (Kinds::eq(Kinds::weaken(st[0], K_object), Kinds::weaken(st[1], K_object))) Rewrite it as a relative comparison6.2 else Rewrite it as an absolute comparison6.1; } return FALSE; }
§6.1. Rewrite it as an absolute comparison6.1 =
Calculus::Schemas::modify(asch->schema, "%k>>*1.%n %s *2", st[0], RTProperties::iname(D->comparative_property), Measurements::strict_comparison(D->comparison_sign)); return TRUE;
- This code is used in §6.
§6.2. Rewrite it as a relative comparison6.2 =
Calculus::Schemas::modify(asch->schema, "%k>>*1.%n %s %k>>*2.%n", st[0], RTProperties::iname(D->comparative_property), Measurements::strict_comparison(D->comparison_sign), st[1], RTProperties::iname(D->comparative_property)); return TRUE;
- This code is used in §6.