For my project, I am trying to create a program that can generate a world that is filled with 'Features' of different types (e.g. People, Settlements, Organisations, etc.) which I have made as subclasses to 'Feature'. These 'Features' are linked together through 'Relationships' (Made up of a subject 'Feature', the predicate, and an object 'Feature' e.g. Person A 'is married to' Person B) where the each Feature should store a reference to the other as well as what type of 'Relationship' links them.
The program will work through iteration; First by generating some 'Features' with random attributes. Then taking some of those 'Features' and giving them a compatible 'Relationship' based on its type and attributes. Then either completing the 'Relationship' with a compatible pre-existing 'Feature' or by generating a new one that is compatible. Then finally making any attribute changes based on the applied 'Relationships' (For example if a relationship is formed Person A is the child of Person B, their last name changes to match). This will go on until certain criteria are met.
A 'Relationship' can vary.
It can be Unidirectional or Bidirectional; If Person A is a sibling of Person B then Person B is a sibling of Person A so it is Bidirectional. Whereas if Person A is the mother of Person B then it is not the same going back, instead it would be Person B is the child of Person A, so it is Unidirectional.
A 'Feature' can either have a Single or Multiple of a type of 'Relationship'; Person A can have multiple siblings, but cannot have multiple (biological) mothers.
A 'Relationship' has constraints as to the types of 'Features' can be the subject and object; The 'Relationship' of a Person is the ruler of a Settlement/a Settlement is ruled by a Person. Now an obvious constraint here is the correct 'Feature' subtype (Person/Settlement) must be used, but also the Settlement can't already have a ruler, as well as the Person must be of a certain age. So attribute and class type checks/filters would need to be implemented.
I am having an issue with how to represent this abstract concept of a 'Relationship', and currently have tried having each 'Feature' hold a HashMap with the keys as the 'Relationship' and the 'Feature' as the value, though this would be actually be two separate links rather than one unifying 'Relationship'. For example, if Person A is the ruler of Settlement B, then Person A would have a HashMap key/value stored of "ruler of" : Settlement B, and Settlement B would have one stored separately of "ruled by" : Person A. Now if later on in the generation, Person C 'killed' Person A, then Person A would no longer be the ruler and its 'Relationship' key/value would be removed, but there is no explicit link to the other 'Relationship' key/value stored in Settlement B, which could potentially result in mismatched Relationships.
I have also tried to implement my own 'Relationship' object type (As well as a 'Predicate' object type, which holds a Feature subject, Feature object, Predicate predicate) but I just can't figure out how to get it to work how I am envisioning the abstract concept in my head.
If you have an idea as to how I could achieve something like this, please let me know and if you need any further clarification please ask.