Setting up the use of this module.

§1. This section simply sets up the module in ways expected by foundation, and contains no code of interest. The following constant exists only in tools which use this module:

define KINDS_MODULE TRUE

§2. This module defines the following classes:

enum dimensional_rule_CLASS
enum kind_CLASS
enum kind_variable_declaration_CLASS
enum kind_constructor_CLASS
enum kind_template_definition_CLASS
enum kind_macro_definition_CLASS
enum kind_constructor_comparison_schema_CLASS
enum kind_constructor_casting_rule_CLASS
enum kind_constructor_instance_CLASS
enum kind_constructor_instance_rule_CLASS
enum arithmetic_schema_CLASS
enum unit_sequence_CLASS
enum star_invention_CLASS
enum additional_property_CLASS
enum additional_property_set_CLASS
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(dimensional_rule, 100)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(kind, 1000)
DECLARE_CLASS(kind_variable_declaration)
DECLARE_CLASS(kind_constructor)
DECLARE_CLASS(kind_macro_definition)
DECLARE_CLASS(kind_template_definition)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(kind_constructor_casting_rule, 100)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(kind_constructor_comparison_schema, 100)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(kind_constructor_instance, 100)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(kind_constructor_instance_rule, 100)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(arithmetic_schema, 50)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(unit_sequence, 50)
DECLARE_CLASS(star_invention)
DECLARE_CLASS(additional_property)
DECLARE_CLASS(additional_property_set)

§3. Like all modules, this one must define a start and end function:

enum KIND_CHANGES_DA
enum KIND_CHECKING_DA
enum KIND_CREATIONS_DA
enum MATCHING_DA
void KindsModule::start(void) {
    Writers::register_writer('u', &Kinds::Textual::writer);
    Writers::register_logger('Q', Kinds::Dimensions::logger);
    Log::declare_aspect(KIND_CHANGES_DA, U"kind changes", FALSE, TRUE);
    Log::declare_aspect(KIND_CHECKING_DA, U"kind checking", FALSE, FALSE);
    Log::declare_aspect(KIND_CREATIONS_DA, U"kind creations", FALSE, FALSE);
    Log::declare_aspect(MATCHING_DA, U"matching", FALSE, FALSE);
    KindsModule::set_internal_NTIs();
}
void KindsModule::end(void) {
}

§4. A little Preform optimisation:

void KindsModule::set_internal_NTIs(void) {
    NTI::give_nt_reserved_incidence_bit(<k-kind>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-kind-of-kind>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-base-kind>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-kind-construction>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-kind-variable-texts>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-kind-variable>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-formal-variable>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-irregular-kind-construction>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-variable-definition>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-single-term>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-optional-term>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-tupled-term>, COMMON_NOUN_RES_NT_BIT);
    NTI::give_nt_reserved_incidence_bit(<k-tuple-list>, COMMON_NOUN_RES_NT_BIT);
}

§5. Some tools using this module will want to push simple error messages out to the command line; others will want to translate them into elaborate problem texts in HTML. So the client is allowed to define PROBLEM_KINDS_CALLBACK to some routine of her own, gazumping this one.

enum DimensionRedundant_KINDERROR from 1
enum DimensionNotBaseKOV_KINDERROR
enum NonDimensional_KINDERROR
enum ImproperSubtraction_KINDERROR
enum UnitSequenceOverflow_KINDERROR
enum DimensionsInconsistent_KINDERROR
enum KindUnalterable_KINDERROR
enum KindsCircular_KINDERROR
enum KindsCircular2_KINDERROR
enum LPCantScaleYet_KINDERROR
enum LPCantScaleTwice_KINDERROR
enum NeptuneError_KINDERROR
void KindsModule::problem_handler(int err_no, parse_node *pn, text_stream *E,
    kind *K1, kind *K2) {
    #ifdef PROBLEM_KINDS_CALLBACK
    PROBLEM_KINDS_CALLBACK(err_no, pn, E, K1, K2);
    #endif
    #ifndef PROBLEM_KINDS_CALLBACK
    TEMPORARY_TEXT(text)
    if (pn) WRITE_TO(text, "%+W", Node::get_text(pn));
    if (E) WRITE_TO(text, "%S", E);
    switch (err_no) {
        case DimensionRedundant_KINDERROR:
            Errors::with_text("multiplication rule given twice: %S", text);
            break;
        case DimensionNotBaseKOV_KINDERROR:
            Errors::with_text("multiplication rule too complex: %S", text);
            break;
        case NonDimensional_KINDERROR:
            Errors::with_text("multiplication rule quotes non-numerical kinds: %S", text);
            break;
        case ImproperSubtraction_KINDERROR:
            Errors::with_text("subtraction rules can only subtract a dimensionless kind from itself", text);
            break;
        case UnitSequenceOverflow_KINDERROR:
            Errors::with_text("multiplication rule far too complex: %S", text);
            break;
        case DimensionsInconsistent_KINDERROR:
            Errors::with_text("multiplication rule creates inconsistency: %S", text);
            break;
        case KindUnalterable_KINDERROR:
            Errors::with_text("making this subkind would lead to a contradiction: %S", text);
            break;
        case KindsCircular_KINDERROR:
            Errors::with_text("making this subkind would lead to a circularity: %S", text);
            break;
        case KindsCircular2_KINDERROR:
            Errors::with_text("making this subkind would a kind being its own subkind: %S", text);
            break;
        case LPCantScaleYet_KINDERROR:
            Errors::with_text("tries to scale a value with no point of reference: %S", text);
            break;
        case LPCantScaleTwice_KINDERROR:
            Errors::with_text("tries to scale a value which has already been scaled: %S", text);
            break;
        case NeptuneError_KINDERROR:
            Errors::with_text("error in Neptune file: %S", text);
            break;
        default: internal_error("unimplemented problem message");
    }
    DISCARD_TEXT(text)
    #endif
}