role Node; class Conjunction with Node { has left => (is => 'ro', does => 'Node'); has right => (is => 'ro', does => 'Node'); } class Disjunction with Node { has left => (is => 'ro', does => 'Node'); has right => (is => 'ro', does => 'Node'); } class Negation with Node { has negated_term => (is => 'ro', does => 'Node'); } class Primative with Node { has label => (is => 'ro', isa => Str); } my $fred = Primative->new(label => "Fred"); my $john = Primative->new(label => "John"); my $fred_and_john = Conjunction->new(left => $fred, right => $john); ...;