Imperative definitions of "Definition: X is Y: ..." adjectives.
§1. This family is used for adjective definitions, whether or not they run on into substantial amounts of code.
imperative_defn_family *adjectival_idf = NULL; "Definition: a container is roomy if: ..." void AdjectivalDefinitionFamily::create_family(void) { adjectival_idf = ImperativeDefinitionFamilies::new(I"adjectival-idf", FALSE); METHOD_ADD(adjectival_idf, IDENTIFY_IMP_DEFN_MTID, AdjectivalDefinitionFamily::identify); METHOD_ADD(adjectival_idf, GIVEN_BODY_IMP_DEFN_MTID, AdjectivalDefinitionFamily::given_body); METHOD_ADD(adjectival_idf, ALLOWS_EMPTY_IMP_DEFN_MTID, AdjectivalDefinitionFamily::allows_empty); METHOD_ADD(adjectival_idf, COMPILE_IMP_DEFN_MTID, AdjectivalDefinitionFamily::compile); }
§2. Colons are used slightly differently in some adjectival definitions. Consider:
Definition: A container is roomy if its carrying capacity is greater than 10. Definition: A container is possessed by the Devil: if its carrying capacity is 666, decide yes; decide no.
To Inform this looks like three consecutive IMPERATIVE_NT nodes:
Definition: A container is roomy if its carrying capacity is greater than 10. Definition: A container is possessed by the Devil: if its carrying capacity is 666, decide yes; decide no.
But we want to create just two imperative_defn objects, not three. So when the second IMPERATIVE_NT node is identified as belonging to us, we take the opportunity to change the type of the third node to DEFN_CONT_NT ("definition continuation"). That means it will not lead to an imperative_defn of its own.
<definition-preamble> ::= definition
- This is Preform grammar, not regular C code.
void AdjectivalDefinitionFamily::identify(imperative_defn_family *self, imperative_defn *id) { wording W = Node::get_text(id->at); if (<definition-preamble>(W)) { id->family = adjectival_idf; if ((id->at->next) && (id->at->down == NULL) && (Node::get_type(id->at->next) == IMPERATIVE_NT)) { ImperativeSubtrees::accept_body(id->at->next); Node::set_type(id->at->next, DEFN_CONT_NT); } AdjectivalDefinitionFamily::look_for_headers(id->at); } }
§5. Since the "Definition:" node might have no code under it (because the code is actually under the continuation node):
int AdjectivalDefinitionFamily::allows_empty(imperative_defn_family *self, imperative_defn *id) { return TRUE; }
§6. The body of code under a definition needs to be set up so that:
- ● The code expects to make a yes/no decision;
- ● The pronoun "it" is a local variable referring to the value being tested, perhaps also with a calling — consider the example "Definition: A container (called the sack) is capacious if...".
void AdjectivalDefinitionFamily::given_body(imperative_defn_family *self, imperative_defn *id) { id_body *body = id->body_of_defn; IDTypeData::set_mor(&(body->type_data), DECIDES_CONDITION_MOR, NULL); wording CALLW = EMPTY_WORDING; kind *K = NULL; AdjectivesByPhrase::define_adjective_by_phrase(id->at, body, &CALLW, &K); Frames::enable_it(&(body->compilation_data.id_stack_frame), CALLW, K); }
§7. The code body for any definition is compiled here:
void AdjectivalDefinitionFamily::compile(imperative_defn_family *self, int *total_phrases_compiled, int total_phrases_to_compile) { imperative_defn *id; LOOP_OVER(id, imperative_defn) if (id->family == adjectival_idf) { RTAdjectives::make_adjective_phrase_package(id->body_of_defn); CompileImperativeDefn::not_from_phrase(id->body_of_defn, total_phrases_compiled, total_phrases_to_compile, NULL, NULL); } RTAdjectives::compile(); }
§8. Implementation details. First, some Preform grammar:
<definition-header> ::= definition <adjective-definition> ::= <adjective-domain> is/are <adjective-wording> if ... | ==> { DEFINED_POSITIVELY, - } <adjective-domain> is/are <adjective-wording> unless ... | ==> { DEFINED_NEGATIVELY, - } <adjective-domain> is/are <adjective-wording> ==> { DEFINED_PHRASALLY, - } <adjective-domain> ::= ... ( called the ... ) | ==> { 0, -, <<calling>> = TRUE } ... ( called ... ) | ==> { 0, -, <<calling>> = TRUE } ... ==> { 0, -, <<calling>> = FALSE } <adjective-wording> ::= ... rather than ... | ==> { 0, -, <<antonym>> = TRUE } ... ==> { 0, -, <<antonym>> = FALSE }
- This is Preform grammar, not regular C code.
§9. The following function provides the method of identification:
define DEFINED_POSITIVELY 1 define DEFINED_NEGATIVELY -1 define DEFINED_PHRASALLY 0 define DEFINED_IN_SOME_WAY_NOT_YET_KNOWN -2
void AdjectivalDefinitionFamily::look_for_headers(parse_node *p) { if (Node::get_type(p) == IMPERATIVE_NT) if (<definition-header>(Node::get_text(p))) { parse_node *q = NULL; if (Node::get_type(p->next) == DEFN_CONT_NT) q = p->next; else q = (p->down)?(p->down->down):NULL; wording DNW = EMPTY_WORDING; domain name wording CALLW = EMPTY_WORDING; calling wording AW = EMPTY_WORDING; adjective name wording NW = EMPTY_WORDING; negation name wording CONW = EMPTY_WORDING; condition text int the_format = DEFINED_IN_SOME_WAY_NOT_YET_KNOWN; Parse the Q-node as an adjective definition9.1; Perform sanity checks on the result9.2; Register the resulting adjective9.3; if (the_format != DEFINED_PHRASALLY) p->down = NULL; } }
§9.1. Parse the Q-node as an adjective definition9.1 =
if (<adjective-definition>(Node::get_text(q))) { the_format = <<r>>; DNW = GET_RW(<adjective-domain>, 1); if (<<calling>>) CALLW = GET_RW(<adjective-domain>, 2); AW = GET_RW(<adjective-wording>, 1); if (<<antonym>>) NW = GET_RW(<adjective-wording>, 2); if (the_format != DEFINED_PHRASALLY) CONW = GET_RW(<adjective-definition>, 1); }
- This code is used in §9.
§9.2. Perform sanity checks on the result9.2 =
if ((the_format == DEFINED_IN_SOME_WAY_NOT_YET_KNOWN) || ((the_format == DEFINED_PHRASALLY) && (q->down == NULL))) { LOG("Definition tree (%d):\n$T\n", the_format, q); StandardProblems::definition_problem(Task::syntax_tree(), _p_(PM_DefinitionWithoutCondition), q, "a definition must take the form 'Definition: a ... is ... if/unless " "...' or else 'Definition: a ... is ...: ...'", "but I can't make this fit either shape."); return; } if ((Wordings::mismatched_brackets(AW)) || ((Wordings::nonempty(NW)) && (Wordings::mismatched_brackets(NW)))) { LOG("Definition tree:\n$T\n", p); StandardProblems::definition_problem(Task::syntax_tree(), _p_(PM_BracketedAdjective), q, "this definition seems to involve unexpected brackets in the name of " "the adjective being defined", "so I think I must be misreading it."); return; }
- This code is used in §9.
§9.3. Register the resulting adjective9.3 =
current_sentence = q; adjective_meaning *am = AdjectiveMeanings::claim_definition(q, the_format, AW, DNW, CONW, CALLW); if (am == NULL) internal_error("unclaimed adjective definition"); if (Wordings::nonempty(NW)) { current_sentence = q; adjective *adj = Adjectives::declare(NW, NULL); adjective_meaning *neg = AdjectiveMeanings::negate(am); AdjectiveAmbiguity::add_meaning_to_adjective(neg, adj); }
- This code is used in §9.
§10. The usual strictures apply:
define ADJECTIVE_NAME_VETTING_LINGUISTICS_CALLBACK AdjectivalDefinitionFamily::vet_name
int AdjectivalDefinitionFamily::vet_name(wording W) { if (<article>(W)) { StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_ArticleAsAdjective), "a defined adjective cannot consist only of an article such as 'a' or 'the'", "since this will lead to parsing ambiguities."); return FALSE; } if (<unsuitable-name>(W)) { if (problem_count == 0) { Problems::quote_source(1, current_sentence); Problems::quote_wording(2, W); StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_AdjectivePunctuated)); Problems::issue_problem_segment( "The sentence %1 seems to create an adjective with the name '%2', but " "adjectives have to be contain only unpunctuated words."); Problems::issue_problem_end(); } return FALSE; } LOOP_THROUGH_WORDING(n, W) NTI::mark_word(n, <s-adjective>); return TRUE; }
typedef struct definition { struct parse_node *definition_node; current sentence: where the word "Definition" is struct parse_node *node; where the actual definition is int format; +1 to go by condition, -1 to negate it, 0 to use routine struct wording condition_to_match; text of condition to match, if +1 or -1 struct wording domain_calling; what if anything the term is called struct adjective_meaning *am_of_def; which adjective meaning CLASS_DEFINITION } definition; definition *AdjectivalDefinitionFamily::new_definition(parse_node *q) { definition *def = CREATE(definition); def->node = q; def->format = 0; def->condition_to_match = EMPTY_WORDING; def->domain_calling = EMPTY_WORDING; def->definition_node = current_sentence; return def; }
- The structure definition is accessed in 8/abp, 8/abc, 8/abif, 8/abic and here.