Passable Relations

version 1 by Ron Newcomb

  • Home page
  • Beginning
  • Previous



  • Chapter 7 - Hard-bitten Inform 6 datacode

    Include (-

    Constant Relation_ByHalfRoutine = 9; ! many I7 relations compile to an I6 function, used like: obj1 == SupporterOf(obj2)
    Constant Relation_ByMapNRoutine = 10; ! in lieu of Relation_ByRoutine this constant must carry addtional data
    Constant Relation_ByMapNERoutine = 11;
    Constant Relation_ByMapNWRoutine = 12;
    Constant Relation_ByMapSRoutine = 13;
    Constant Relation_ByMapSERoutine = 14;
    Constant Relation_ByMapSWRoutine = 15;
    Constant Relation_ByMapERoutine = 16;
    Constant Relation_ByMapWRoutine = 17;
    Constant Relation_ByMapURoutine = 18;
    Constant Relation_ByMapDRoutine = 19;
    Constant Relation_ByMapIRoutine = 20;
    Constant Relation_ByMapORoutine = 21;

    Array relation_metadata_testfunctions -->
    (0) ! this is index 0, the "is" relation. it has no Inform7 name that I know of
    ContainerOf ContainerOf
    SupporterOf SupporterOf
    component_parent component_parent
    CarrierOf CarrierOf
    HolderOf HolderOf
    WearerOf WearerOf
    OwnerOf OwnerOf
    TestVisibility TestVisibility
    TestTouchability TestTouchability
    TestConcealment TestConcealment
    IndirectlyContains IndirectlyContains
    TestAdjacency TestAdjacency
    TestRegionalContainment TestRegionalContainment
    0 0 ! greater than, less than. Can't deal with these numerical relations. Leave 'em untouched
    0 0
    0 0
    0 0
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    MapConnection MapConnection
    NULL;

    Array relation_metadata_relationtypes -->
    (-1) ! this is index 0, the "is" relation
    Relation_ByHalfRoutine (-1)
    Relation_ByHalfRoutine (-1)
    Relation_OtoV (-1)
    Relation_ByHalfRoutine (-1)
    Relation_ByHalfRoutine (-1)
    Relation_ByHalfRoutine (-1)
    Relation_ByHalfRoutine (-1)
    Relation_ByRoutine (-1)
    Relation_ByRoutine (-1)
    Relation_ByRoutine (-1)
    Relation_ByRoutine (-1)
    Relation_ByRoutine (-1)
    Relation_ByRoutine (-1)
    Relation_Implicit (-1) ! greater than, less than. Can't deal with these numerical relations
    Relation_Implicit (-1)
    Relation_Implicit (-1)
    Relation_Implicit (-1)
    Relation_ByMapNRoutine (-1)
    Relation_ByMapNERoutine (-1)
    Relation_ByMapNWRoutine (-1)
    Relation_ByMapSRoutine (-1)
    Relation_ByMapSERoutine (-1)
    Relation_ByMapSWRoutine (-1)
    Relation_ByMapERoutine (-1)
    Relation_ByMapWRoutine (-1)
    Relation_ByMapURoutine (-1)
    Relation_ByMapDRoutine (-1)
    Relation_ByMapIRoutine (-1)
    Relation_ByMapORoutine (-1)
    NULL;

    [ RepairRelationMetadata x i; ! adds to the relation_metadata array the Inform6 routines used by the most basic built-in relations
        x = 3;
        for (i = 1; i < 59; i++) {
            relation_metadata-->(x) = relation_metadata_testfunctions-->(i);
            relation_metadata-->(x+1) = relation_metadata_relationtypes-->(i);
    x = x + 3;
        }
    ];

    [ NumberOfRelations; return {-value:NUMBER_CREATED(binary_predicate)} - 1; ];

    [ RelationName rel; return relation_metadata-->((rel*3)+2); ];

    [ RelationKind rel i;
        i = relation_metadata-->((rel*3)+1);
        if ((i == -1) && (rel ~= 0) && ((rel & 1) == 0)) return 2;
        return i + 2;
    ];

    [ SymRelation_Test obj1 rel_num obj2;
        if (Relation_Test(obj1, rel_num, obj2)) rtrue;
        return Relation_Test(obj2, rel_num, obj1);
    ];

    [ Relation_Test obj1 rel_num obj2 rel_prop rel_type x pr pr2;
        if (obj1 == nothing || obj2 == nothing) rfalse;
        x = rel_num*3;
        rel_type = relation_metadata-->(x+1);
        rel_prop = relation_metadata-->(x);
        switch(rel_type) {
        Relation_OtoO: return ((obj2 provides rel_prop) && (obj2.rel_prop == obj1));
        Relation_Sym_OtoO: return ((obj2 provides rel_prop) && (obj2.rel_prop == obj1));
        Relation_OtoV: return ((obj2 provides rel_prop) && (obj2.rel_prop == obj1));
        Relation_VtoO: return ((obj1 provides rel_prop) && (obj1.rel_prop == obj2));
        Relation_Equiv: return ((obj1 provides rel_prop) && (obj2 provides rel_prop) && (obj1.rel_prop == obj2.rel_prop));
        Relation_ByRoutine: return rel_prop(obj1, obj2);
        Relation_ByHalfRoutine: return (obj1 == rel_prop(obj2));
        Relation_ByMapNRoutine: return (rel_prop(obj2, DirectionObject_0) == obj1);
        Relation_ByMapNERoutine: return (rel_prop(obj2, DirectionObject_1) == obj1);
        Relation_ByMapNWRoutine: return (rel_prop(obj2, DirectionObject_2) == obj1);
        Relation_ByMapSRoutine: return (rel_prop(obj2, DirectionObject_3) == obj1);
        Relation_ByMapSERoutine: return (rel_prop(obj2, DirectionObject_4) == obj1);
        Relation_ByMapSWRoutine: return (rel_prop(obj2, DirectionObject_5) == obj1);
        Relation_ByMapERoutine: return (rel_prop(obj2, DirectionObject_6) == obj1);
        Relation_ByMapWRoutine: return (rel_prop(obj2, DirectionObject_7) == obj1);
        Relation_ByMapURoutine: return (rel_prop(obj2, DirectionObject_8) == obj1);
        Relation_ByMapDRoutine: return (rel_prop(obj2, DirectionObject_9) == obj1);
        Relation_ByMapIRoutine: return (rel_prop(obj2, DirectionObject_10) == obj1);
        Relation_ByMapORoutine: return (rel_prop(obj2, DirectionObject_11) == obj1);
        Relation_Implicit: print "[Can't test relation #", rel_num, " between ", (the) obj1, " and ", (the) obj2, ".]^";
                        rfalse;
        Relation_VtoV: break; ! implemented below
        Relation_Sym_VtoV: break; ! implemented below
        default: rfalse; ! the switch should catch every kind of relation there is, but just in case, return false
        }
        ! first ensure we aren't doing something like passing a Thing to a Person-to-Person relation (if so, just rfalse)
        if (~~(obj1 ofclass Object && obj2 ofclass Object)) rfalse;
        pr = rel_prop-->VTOVS_LEFT_INDEX_PROP;
        pr2 = rel_prop-->VTOVS_RIGHT_INDEX_PROP;
        if (~~(obj1 provides pr || obj1 provides pr2)) rfalse;
        if (~~(obj2 provides pr || obj2 provides pr2)) rfalse;
        return Relation_TestVtoV(obj1, rel_prop, obj2, (rel_type == Relation_Sym_VtoV));
    ];

    -).



    [ Relation_SetTrue obj1 rel_num obj2 rel_type rel_prop x;
        if (obj1 == nothing || obj2 == nothing) rfalse;
        x = rel_num*3;
        rel_type = relation_metadata-->(x+1);
        rel_prop = relation_metadata-->(x);
        switch (rel_type) {
        Relation_OtoO: Relation_Now1to1(obj1, rel_prop, obj2); rtrue;
        Relation_OtoV: if (obj2 provides rel_prop) obj2.rel_prop = obj1; rtrue;
        Relation_VtoO: if (obj2 provides rel_prop) obj2.rel_prop = obj1; rtrue;
        Relation_Sym_OtoO: Relation_NowSN1to1(obj1, rel_prop, obj2); ! unset the old...
                        Relation_NowS1to1(obj1, rel_prop, obj2); ! and set the new
                        rtrue;
        Relation_Equiv: Relation_NowEquiv(obj1, rel_prop, obj2); rtrue;
        Relation_ByRoutine: rfalse; ! can't set; how would this get by the Inform 7 compiler?
        Relation_ByHalfRoutine:
                        switch (rel_type) {
                        (+ the incorporation relation +): MakePart(obj2, obj1); rtrue;
                        (+ the wearing relation +): WearObject(obj2, obj1); rtrue;
                        default: MoveObject(obj2, obj1); rtrue;
                        }
        Relation_Implicit: rfalse; ! can't set; how would this get by the Inform 7 compiler?
        Relation_VtoV: break; ! implemented below
        Relation_Sym_VtoV: break; ! implemented below
        Relation_ByMapNRoutine: AssertMapConnection(obj1, DirectionObject_0, obj2); rtrue;
        Relation_ByMapNERoutine: AssertMapConnection(obj1, DirectionObject_1, obj2); rtrue;
        Relation_ByMapNWRoutine: AssertMapConnection(obj1, DirectionObject_2, obj2); rtrue;
        Relation_ByMapSRoutine: AssertMapConnection(obj1, DirectionObject_3, obj2); rtrue;
        Relation_ByMapSERoutine: AssertMapConnection(obj1, DirectionObject_4, obj2); rtrue;
        Relation_ByMapSWRoutine: AssertMapConnection(obj1, DirectionObject_5, obj2); rtrue;
        Relation_ByMapERoutine: AssertMapConnection(obj1, DirectionObject_6, obj2); rtrue;
        Relation_ByMapWRoutine: AssertMapConnection(obj1, DirectionObject_7, obj2); rtrue;
        Relation_ByMapURoutine: AssertMapConnection(obj1, DirectionObject_8, obj2); rtrue;
        Relation_ByMapDRoutine: AssertMapConnection(obj1, DirectionObject_9, obj2); rtrue;
        Relation_ByMapIRoutine: AssertMapConnection(obj1, DirectionObject_10, obj2); rtrue;
        Relation_ByMapORoutine: AssertMapConnection(obj1, DirectionObject_11, obj2); rtrue;
        default: rfalse;
        }
        if (rel_type == Relation_Sym_VtoV) Relation_NowNVtoV(obj1, rel_prop, obj2, true); ! unset the old
        Relation_NowVtoV (obj1, rel_prop, obj2, (rel_type == Relation_Sym_VtoV)); ! set the new
        rtrue;
    ];


    [ Relation_SetFalse obj1 rel_num obj2 rel_type rel_prop x;
        if (obj1 == nothing || obj2 == nothing) rfalse;
        x = rel_num*3;
        rel_type = relation_metadata-->(x+1);
        rel_prop = relation_metadata-->(x);
        switch (rel_type) {
        Relation_OtoO: Relation_NowN1toV(obj1, rel_prop, obj2); rtrue;
        Relation_OtoV: Relation_NowN1toV(obj1, rel_prop, obj2); rtrue;
        Relation_VtoO: if (obj2 provides rel_prop) obj2.rel_prop = nothing; rtrue;
        Relation_Sym_OtoO: Relation_NowSN1to1(obj1, rel_prop, obj2); ! unset the old...
                        rtrue;
        Relation_Equiv: Relation_NowNEquiv(obj1, rel_prop, obj2); rtrue;
        Relation_ByRoutine: rfalse; ! can't set; how would this get by the Inform 7 compiler?
        Relation_ByHalfRoutine:
                        switch (rel_type) {
                        (+ the incorporation relation +): DetachPart(obj2, obj1); rtrue;
                        default: MoveObject(obj2, obj1); rtrue;
                        }
        Relation_Implicit: rfalse; ! can't set; how would this get by the Inform 7 compiler?
        Relation_VtoV: Relation_NowNVtoV(obj1, rel_prop, obj2, false); rtrue;
        Relation_Sym_VtoV: Relation_NowNVtoV(obj1, rel_prop, obj2, true ); rtrue;
        Relation_ByMapNRoutine: AssertMapUnconnection(obj1, DirectionObject_0, obj2); rtrue;
        Relation_ByMapNERoutine: AssertMapUnconnection(obj1, DirectionObject_1, obj2); rtrue;
        Relation_ByMapNWRoutine: AssertMapUnconnection(obj1, DirectionObject_2, obj2); rtrue;
        Relation_ByMapSRoutine: AssertMapUnconnection(obj1, DirectionObject_3, obj2); rtrue;
        Relation_ByMapSERoutine: AssertMapUnconnection(obj1, DirectionObject_4, obj2); rtrue;
        Relation_ByMapSWRoutine: AssertMapUnconnection(obj1, DirectionObject_5, obj2); rtrue;
        Relation_ByMapERoutine: AssertMapUnconnection(obj1, DirectionObject_6, obj2); rtrue;
        Relation_ByMapWRoutine: AssertMapUnconnection(obj1, DirectionObject_7, obj2); rtrue;
        Relation_ByMapURoutine: AssertMapUnconnection(obj1, DirectionObject_8, obj2); rtrue;
        Relation_ByMapDRoutine: AssertMapUnconnection(obj1, DirectionObject_9, obj2); rtrue;
        Relation_ByMapIRoutine: AssertMapUnconnection(obj1, DirectionObject_10, obj2); rtrue;
        Relation_ByMapORoutine: AssertMapUnconnection(obj1, DirectionObject_11, obj2); rtrue;
        default: rfalse;
        }
        rfalse;
    ];






    Passable Relations ends here.