jgraley / inferno-cpp2v

2 stars 0 forks source link

Drop finality requirement #594

Open jgraley opened 2 years ago

jgraley commented 2 years ago
src/sr$ grep IsFinal -rn .
./agents/standard_agent.cpp:537:        ASSERT( under_node->IsFinal() ); 
./agents/standard_agent.cpp:547:        ASSERT( key_node->IsFinal() ); 
./agents/standard_agent.cpp:554:        ASSERT( me_plink.GetPattern()->IsFinal() ); 
./agents/standard_agent.cpp:582:    ASSERT( under_node->IsFinal() )("About to build non-final ")(*dest)("\n"); 
./agents/standard_agent.cpp:587:    ASSERT( dest->IsFinal() )("About to build non-final ")(*dest)("\n"); 
./agents/standard_agent.cpp:626:                    ASSERT( new_elt->IsFinal() )("Got intermediate node ")(*new_elt);
./agents/standard_agent.cpp:644:                ASSERT( new_dest_singular->IsFinal() );
./agents/standard_agent.cpp:694:                    ASSERT( new_elt->IsFinal() );
./agents/standard_agent.cpp:706:            ASSERT( (**dest_singular).IsFinal() );            
./agents/standard_agent.cpp:728:    ASSERT( dest->IsFinal() )(*this)(" about to build non-final ")(*dest)("\n"); 
./agents/agent_common.cpp:527:    ASSERT( !keynode || keynode->IsFinal() )(*this)(" keyed with non-final node ")(keynode)("\n"); 
./agents/agent_common.cpp:532:    ASSERT( dest->IsFinal() )(*this)(" built non-final ")(*dest)("\n"); 
./agents/agent_common.cpp:648:            ASSERT( TreePtr<Node>(*dest_singular)->IsFinal() );            
./agents/transform_of_agent.cpp:23:        ASSERT( trans_x->IsFinal() )(*this)(" computed non-final ")(*trans_x)(" from ")(base_x)("\n");                      

suggests that IsFinal() is only ever used in checks (14 of them). And yet

struct Label : Declaration, //TODO commonize with Case and Default
               Statement,
               Uncombable
{
    NODE_FUNCTIONS_FINAL
    TreePtr<LabelIdentifier> identifier; ///< a handle for the label to be referenced elewhere
    virtual string GetColour() const { return Declaration::GetColour(); } // Declaration wins
};

plus

struct StateLabel : Label
{
    NODE_FUNCTIONS_FINAL
    TreePtr<InstanceIdentifier> state;
};

(found in fall_out.cpp) flouts the rule, and gets away with it (until I tried using IsFinal() to solve #588 - found a different way though).

So can finality of X tree nodes be relaxed? The rule is consistent with usage styles in which intermediates form a category system for the nodes that go in the X trees.

But another use case for inheritance is "bolt-ons" where you want to add a specialization of part of an existing hierarchy without disrupting that hierarchy (as with StateLabel). To be final-correct, a category of labels would need to be introduced eg LabelCat, and then existing patterns would need to be updated to use LabelCat when allowing StateLabel, which presumably wants to stealthily masquerade as a Label until searched for explicitly (OTOH, to exclude StateLabel, a but-not pattern could be used).

We could just remove IsFinal() etc and all the asserts and see what happens, but the implications should be contemplated and docs updated. Note that truly final nodes F have "X is (weak) subcategory of F" implies "X is F". There maybe assumptions along these lines after the ASSERTs listed above. So extra checks like "is F (weak) subcategory of X" might need to be added to prevent type mismatch errors emerging later.

jgraley commented 2 years ago

Of course, we have to consider the implications of patterns containing more-derived nodes than the ones in the X tree they are interacting with. But it's probably quite simple:

Policy could be described as "maximise specialisation" or "don't de-specialise"