[Declarations::] Declarations. Reading declarations from a file. @h Keeping the syntax module happy. We are going to need to use the sentence-breaking apparatus from the //syntax// module, which means that the following four nonterminals need to exist. But in fact they are really just placeholders -- they are wired so that they can never match any text. = ::= ... ==> { fail } ::= ... ==> { fail } ::= ... ==> { fail } ::= ... ==> { fail } @h REPL variables. @e repl_var_CLASS @e named_function_CLASS @e named_unary_predicate_CLASS = DECLARE_CLASS(repl_var) DECLARE_CLASS(named_function) DECLARE_CLASS(named_unary_predicate) typedef struct repl_var { struct wording name; struct pcalc_prop *val; CLASS_DEFINITION } repl_var; typedef struct named_function { struct wording name; struct binary_predicate *bp; int side; CLASS_DEFINITION } named_function; typedef struct named_unary_predicate { struct wording name; struct unary_predicate *up; CLASS_DEFINITION } named_unary_predicate; internal { repl_var *rv; LOOP_OVER(rv, repl_var) if (Wordings::match(rv->name, W)) { ==> { -, rv }; return TRUE; } rv = CREATE(repl_var); rv->val = NULL; rv->name = W; ==> { -, rv }; return TRUE; } internal { repl_var *rv; LOOP_OVER(rv, repl_var) if (Wordings::match(rv->name, W)) { ==> { -, rv }; return TRUE; } return FALSE; } internal { named_function *nf; LOOP_OVER(nf, named_function) if (Wordings::match(nf->name, W)) { ==> { -, nf }; return TRUE; } return FALSE; } internal { named_unary_predicate *nup; LOOP_OVER(nup, named_unary_predicate) if (Wordings::match(nup->name, W)) { ==> { -, nup->up }; return TRUE; } return FALSE; } @h A sort of REPL. The following function reads a file whose name is in |arg|, feeds it into the lexer, builds a syntax tree of its sentences, and then walks through that tree, applying the Preform nonterminal to each sentence. In effect, this is a read-evaluate-print loop. = parse_node_tree *syntax_tree = NULL; text_stream *test_err = NULL; void Declarations::load_from_file(text_stream *arg) { filename *F = Filenames::from_text(arg); feed_t FD = Feeds::begin(); source_file *sf = TextFromFiles::feed_into_lexer(F, NULL_GENERAL_POINTER); wording W = Feeds::end(FD); if (sf == NULL) { PRINT("File has failed to open\n"); return; } syntax_tree = SyntaxTree::new(); Sentences::break(syntax_tree, W); BinaryPredicateFamilies::first_stock(); test_err = Str::new(); SyntaxTree::traverse(syntax_tree, Declarations::parse); } void Declarations::parse(parse_node *p) { if (Node::get_type(p) == SENTENCE_NT) { wording W = Node::get_text(p); (W); } } @ = ::= new unary ### | ==> @ new binary ### ( ### , ### ) | ==> @ set to | ==> @ term | ==> @ constant underlying | ==> @ variable underlying | ==> @ variable unused in | ==> @ variables in | ==> @ | ==> @ | ==> @ ... ==> @ ::= ( ) | ==> { pass 1 } concatenate | ==> { -, Propositions::concatenate(RP[1], RP[2]) } conjoin | ==> { -, Propositions::conjoin(RP[1], RP[2]) } copy of | ==> { -, Propositions::copy(RP[1]) } negation of | ==> { -, Propositions::negate(RP[1]) } unnegation of | ==> { -, Propositions::unnegate(RP[1]) } renumbering of | ==> { -, Binding::renumber(RP[1], NULL) } binding of | ==> { -, Binding::bind_existential(RP[1], NULL) } substitution of = in | ==> @ insert at in | ==> @ delete from | ==> @ remove universal quantifier from | ==> { -, Propositions::trim_universal_quantifier(RP[1]) } remove close domain from | ==> { -, Propositions::remove_final_close_domain(RP[1], NULL) } | ==> { -, Propositions::copy(((repl_var *) RP[1])->val) } ==> { pass 1 } ::= is syntactically valid | ==> { Propositions::is_syntactically_valid(RP[1], test_err), - } is well-formed | ==> { Binding::is_well_formed(RP[1], test_err), - } is complex | ==> { Propositions::is_complex(RP[1]), - } contains relation | ==> { Propositions::contains_binary_predicate(RP[1]), - } contains quantifier | ==> { Propositions::contains_quantifier(RP[1]), - } is a group ==> { Propositions::is_a_group(RP[1], NEGATION_OPEN_ATOM), - } ::= << >> | ==> { pass 1 } << >> | ==> { pass 1 } << >> ==> { -, NULL } ::= \: | ==> { -, Propositions::concatenate(RP[1], RP[2]) } in< in> \: | ==> @; not< not> | ==> { -, Propositions::negate(RP[1]) } \^ | ==> { -, Propositions::concatenate(RP[1], RP[2]) } ==> { pass 1 } ::= ( ) | ==> { -, Atoms::unary_PREDICATE_new(RP[1], *((pcalc_term *) RP[2])) } ( == ) | ==> { -, Atoms::binary_PREDICATE_new(R_equality, *((pcalc_term *) RP[1]), *((pcalc_term *) RP[2])) } ( , ) | ==> { -, Atoms::binary_PREDICATE_new(RP[1], *((pcalc_term *) RP[2]), *((pcalc_term *) RP[3])) } kind = ( ) | ==> { -, KindPredicates::new_atom(RP[1], *((pcalc_term *) RP[2])) } not< | ==> { -, Atoms::new(NEGATION_OPEN_ATOM) } not> | ==> { -, Atoms::new(NEGATION_CLOSE_ATOM) } in< | ==> { -, Atoms::new(DOMAIN_OPEN_ATOM) } in> ==> { -, Atoms::new(DOMAIN_CLOSE_ATOM) } ::= | ==> { -, Declarations::stash(Terms::new_variable(R[1])) } | ==> { -, Declarations::stash(Terms::new_constant(Declarations::number_to_value(W, R[1]))) } ( ) | ==> { -, Declarations::stash(Terms::new_function(((named_function *) RP[1])->bp, *((pcalc_term *) RP[2]), ((named_function *) RP[1])->side)) } first cited in ==> { -, Declarations::stash(Propositions::get_first_cited_term(RP[1])) } ::= ==> { -, Atoms::QUANTIFIER_new(RP[1], R[2], R[1]) } ::= ForAll | ==> { 0, for_all_quantifier } NotAll | ==> { 0, not_for_all_quantifier } Exists | ==> { 0, exists_quantifier } DoesNotExist | ==> { 0, not_exists_quantifier } AllBut | ==> { R[1], all_but_quantifier } NotAllBut | ==> { R[1], not_all_but_quantifier } Proportion>=80% | ==> { R[1], almost_all_quantifier } Proportion<20% | ==> { R[1], almost_no_quantifier } Proportion>50% | ==> { R[1], most_quantifier } Proportion<=50% | ==> { R[1], under_half_quantifier } Card>= | ==> { R[1], at_least_quantifier } Card<= | ==> { R[1], at_most_quantifier } Card= | ==> { R[1], exactly_quantifier } Card< | ==> { R[1], less_than_quantifier } Card> | ==> { R[1], more_than_quantifier } Card~= ==> { R[1], other_than_quantifier } ::= x | ==> { 0, - } y | ==> { 1, - } z ==> { 2, - } @ = pcalc_term *V = RP[1]; pcalc_term *T = RP[2]; pcalc_prop *P = RP[3]; int bogus = 0; ==> { -, Binding::substitute_term(P, V->variable, *T, FALSE, &bogus, &bogus) } @ = pcalc_prop *P = RP[3]; pcalc_prop *pos = NULL; for (int i=0; inext); ==> { -, Propositions::insert_atom(P, pos, RP[1]) } @ = pcalc_prop *P = RP[2]; pcalc_prop *pos = NULL; for (int i=0; inext); ==> { -, Propositions::delete_atom(P, pos) } @ = ==> { -, Propositions::quantify_using(RP[1], RP[2], RP[3]) } @ = Declarations::new_unary(GET_RW(, 1), K_number); PRINT("'% = Declarations::new(GET_RW(, 1), K_number, GET_RW(, 2), K_number, GET_RW(, 3)); PRINT("'% = pcalc_prop *P = RP[2]; repl_var *rv = RP[1]; rv->val = P; PRINT("'%name); Propositions::write(STDOUT, P); PRINT("\n"); @ = pcalc_term *T = RP[1]; PRINT("'% = pcalc_term *T = RP[1]; PRINT("'% = pcalc_term *T = RP[1]; PRINT("'% = pcalc_prop *P = RP[1]; PRINT("'% = pcalc_prop *P = RP[1]; PRINT("'% = PRINT("'% 0) PRINT(" - %S", test_err); } Str::clear(test_err); PRINT("\n"); @ = int var_states[26]; TEMPORARY_TEXT(err) int happy = Binding::determine_status(RP[1], var_states, err); PRINT("'% = PRINT("Declaration not understood: '%W'\n", W); ==> { fail } @ = bp_family *test_bp_family = NULL; up_family *test_up_family = NULL; void Declarations::new_unary(wording W, kind *k0) { if (test_up_family == NULL) { test_up_family = UnaryPredicateFamilies::new(); METHOD_ADD(test_up_family, LOG_UPF_MTID, Declarations::log_unary); } named_unary_predicate *nup = CREATE(named_unary_predicate); nup->up = UnaryPredicates::new(test_up_family); nup->up->assert_kind = k0; nup->up->calling_name = W; nup->name = W; } void Declarations::new(wording W, kind *k0, wording f0, kind *k1, wording f1) { if (test_bp_family == NULL) test_bp_family = BinaryPredicateFamilies::new(); bp_term_details t0 = BPTerms::new(TERM_DOMAIN_FROM_KIND_FUNCTION(k0)); bp_term_details t1 = BPTerms::new(TERM_DOMAIN_FROM_KIND_FUNCTION(k1)); text_stream *S = Str::new(); WRITE_TO(S, "%W", W); binary_predicate *bp = BinaryPredicates::make_pair(test_bp_family, t0, t1, S, NULL, NULL, Calculus::Schemas::new("%S(*1, *2)", S), WordAssemblages::from_wording(W)); TEMPORARY_TEXT(f0n) TEMPORARY_TEXT(f1n) WRITE_TO(f0n, "%W", f0); WRITE_TO(f1n, "%W", f1); if (Str::ne(f0n, I"none")) { named_function *nf = CREATE(named_function); nf->bp = bp; nf->name = f0; nf->side = 1; BPTerms::set_function(&(bp->term_details[0]), Calculus::Schemas::new("%S(*1)", f0n)); } if (Str::ne(f1n, I"none")) { named_function *nf = CREATE(named_function); nf->bp = bp; nf->name = f1; nf->side = 0; BPTerms::set_function(&(bp->term_details[1]), Calculus::Schemas::new("%S(*1)", f1n)); } DISCARD_TEXT(f0n) DISCARD_TEXT(f1n) } int stashed = 0; pcalc_term stashed_terms[1000]; pcalc_term *Declarations::stash(pcalc_term t) { if (stashed == 1000) internal_error("too many terms in test case"); stashed_terms[stashed] = t; return &(stashed_terms[stashed++]); } parse_node *Declarations::number_to_value(wording W, int n) { return Diagrams::new_UNPARSED_NOUN(W); } void Declarations::log_unary(up_family *self, OUTPUT_STREAM, unary_predicate *up) { WRITE("%W", up->calling_name); }