Willem
Willem

Reputation: 81

How to formulate logical relations beween entity objects?

I have two classes, entities and relationships, and I want to define as many relationships of any type between all entities. Besides that I want not only to create a type of relationship between two entities in code but define any type of relationship between two entities at runtime so this needs to be flexible. I want to see the relationships to any entity from any entity. So I want to see all relationships between two entities without defining them both. If I say, for example that male A is the brother of female B It should infer that B is A's sister, without explicitly defining that. So some kind of Prolog functionality in C#. It's just that I can't figure out how to do this.

edit: what I want to do is to define the persons and relationships in, for example, the history of the beginning of the Roman Empire. All mainstream genealogy software doesn't account for things like incest so it is quite impossible to map Robert Graves' biography of the first Roman emperors and their relationships in a model that is capable of generating a family tree based on any member of that dynasty, which I want to do by utilising some kind of algorithm that I've not discovered yet.

Upvotes: 0

Views: 223

Answers (1)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112482

Here is a raw scetch of classes representing your relations:

public class Entity
{
    public Entity()
    {
        RelationsTo = new List<Relation>();
        RelationsFrom = new List<Relation>();
    }

    public string Name { get; set; }
    public List<Relation> RelationsTo { get; private set; }
    public List<Relation> RelationsFrom { get; private set; }
}

public class RelationKind
{
    public string Forwards { get; set; }
    public string Backwards { get; set; }
}

public class Relation
{
    public RelationKind Kind { get; set; }
    public Entity From { get; set; }
    public Entity To { get; set; }
}

An example of a relation kind could be:

var hasChild = new RelationKind { 
    Forwards = "is parent of", 
    Backwards = "is child of" 
};

This allows you to infer that if someone is a parent of someone else, this other person is the child of the first one.

Set up a relation like this:

var dad = new Entity { Name = "Dad" };
var joey = new Entity { Name = "Joey" };
var isDadOfJoey = new Relation { From = dad, To = joey, Kind = hasChild };
dad.RelationsTo.Add(isDadOfJoey);
joey.RelationsFrom.Add(isDadOfJoey);

But I would create a helper method that does this wire up automatically.

public static void CreateRelation(Entity from, RelationKind kind, Entity to)
{
    var relation = new Relation { From = from, To = to, Kind = kind };
    from.RelationsTo.Add(relation);
    to.RelationsFrom.Add(relation);
}

You would call it like this:

CreateRelation(dad, hasChild, joey);

This test

Console.WriteLine("{0} {1} {2}",
    dad.Name,
    dad.RelationsTo[0].Kind.Forwards,
    dad.RelationsTo[0].To.Name);
Console.WriteLine("{0} {1} {2}",
    joey.Name,
    joey.RelationsFrom[0].Kind.Backwards,
    joey.RelationsFrom[0].From.Name);

Prints

Dad Is parent of Joey
Joey Is child of Dad

Upvotes: 2

Related Questions