Whilst writing the final sentences of my previous blog about how something
would be easier to do in SQL, I started thinking about the representation of
data in Prolog. It started by my adding a fact, cd ('Liege and Lief',
'Fairport Convention'). If I queried which Fairport cds were in the
database, then only one cd (Liege and Lief) would be found, and if I queried
which Fairport cds are owned by somebody in the database, then again only
one cd (Unhalfbricking) would be found. As CoPilot puts it, Right now, your database only knows about owns/2 facts, and
the embedded terms like cd(Title,Artist) or
book(Title,Author) are just data structures inside those facts.
If you want to query them directly, you need a mechanism that “lifts” those
embedded terms into their own predicate space.
In SQL, there would be a table of cds and a separate table of ownership whose primary key would be a composite of a person and a cd. Other data such as date of purchase can be added. Relational databases have the key property that every datum is stored only once, and if that datum is needed elsewhere, then it is referred to (that's the 'relational' part).
But Prolog isn't like that and I have to remember that it's not a relational database. If I own a copy of 'Unhalfbricking' and Yossi does as well, then the two clauses about the cd are not the same, although they should unify. I wonder whether it would be possible to have facts like cd (Key, Title, Artist), so that 'Unhalfbricking' could be stored as cd (1, 'Unhalfbricking', 'Fairport Convention). Then there could be clauses such as owns (noam, 1) and owns (yossi, 1). But I suspect that the concept of an SQL join does not exist in Prolog.
So what can I do to query both a list of cds and to show who owns what? There are various solutions to this, either by writing a rule in Prolog that stores embedded clauses as facts in their own right, or even adding the necessary code to the parser. This is a bit irregular but possible. As they say, it'll be a righteous hack. I did add the necessary code but added a global flag to prevent this, should the user so desire. When adding such a fact to the database, it should be checked that it doesn't already exist; Prolog has no problem with duplicate facts but it tends to ruin solutions.
| Title | Tags | ||
|---|---|---|---|
| 309 | The gravy boat | Cooking | |
| 310 | Copper socks 2 | Health, Copper | |
| 1093 | Two more people have passed away | Obituary | |
| 1864 | Management email problems | Programming, Delphi, Email, Threads |
No comments:
Post a Comment