2

Given a set of facts of the form is_member(country, organisation), I have the following query to write in datalog:

Return all countries who belong to all of the organisations of which Denmark is a member of.

I want to do something like

member_all_Denmarks_organisations(Country):- ¬( is_member('Denmark', Organization), ¬is_member(Country, Organization) ).

In other words, 'for every organization that Denmark is member of, Country is a member of it too'. But datalog does not allow negated predicates which contain non-instantiated variables, so this doesn't work.

How can I proceed? And in general, when wanting to express a 'for all' statement, how to do so in datalog?

Alexandre Holden Daly
  • 6,944
  • 5
  • 25
  • 36

2 Answers2

0

We are going to take the following alternative equivalent definition:

Return all countries who not fail to belong to some organisation that Denmark is a member of.

Of course, you can only express this in a dialect of Datalog with negation. The following should do:

organisation_of_denmark(org) :- is_member('Denmark', org).

// a country c is disqualified if there is some organisation org 
// of which Denmark is a member but c isn't  
disqualified_country(c) :- organisation_of_denmark(org), country(c), ¬is_member(c, org). 

// we are only interested in countries that are not excluded by the previous rule
mmember_all_Denmarks_organisations(c) :- country(c), ¬disqualified_country(c). 

// in case there is no unary predicate identifying all countries 
// the best we can do is the following (knowing well that then the above 
// will only work for countries that are members of at least one organisation)
country(c) :- is_member(c, _).

This is precisely what you wrote also, only with intermediate relations included that capture some of your sub-formulas and with the atom country(c) included to act as a guard or a domain for the outer-most complementation.

Alexandre Holden Daly
  • 6,944
  • 5
  • 25
  • 36
Hamlet
  • 1
0

The problem is a case of expressing the following proposition P in Datalog:

P(x) := for all y, p(y) => q(x,y)

In Datalog, given database DB with, say, 2 columns and x in 1st column, this can be expressed as:

P(x):- DB(x,_), ¬disqualified(x).
disqualified(x):- DB(x,_), p(y), ¬q(x,y).

The trick is to create your own disqualified() predicate. DB(x,_) is there just to instantiate x before it appears in a negated predicate.


In the specific Denmark case:

P(x) =: 'x is member of all Denmark's organisations'

p(y) =: is_member('Denmark', y)

q(x,y) =: is_member(x,y)

DB =: is_member()

Alexandre Holden Daly
  • 6,944
  • 5
  • 25
  • 36