The n-ary predicates in traditional Datalog are actually similar to tables in relational databases. So for example the following line would add information about a person in a traditional Datalog system:
assert Person("John", "Smith", "1985-01-01")
Notice that the only thing that tells you that the 3rd value is the date of birth is it's position in the predicate.
Datomic does not use free-form predicates like this to store the data. It uses Datalog strictly on the query side. To represent something like our person above in Datomic you would need to create three attributes. You could call the attributes: :person/first-name
, :person/last-name
, :person/dob
(note that :person/
is just part of the name, it doesn't actually create any kind of structure or table-like thing).
Each attribute needs to be installed using the transact
function before you can use it. Here's an example of what you need to send to transact for :person/last-name
[{:db/id #db/id[:db.part/db]
:db/ident :person/last-name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/fulltext true
:db/doc "A person's last name"
:db.install/_attribute :db.part/db}]
You can find more details in Datomic's documentation: http://docs.datomic.com/schema.html
Once you have the attributes you can add the same information we started with by transacting the following:
[{:db/id #db/id[:db.part/user]
:person/first-name "John"
:person/last-name "Smith"
:person/dob "1985-01-01"}]
So the short answer is: no Datomic doesn't do n-ary predicates on the input side but there's nothing you can represent in an n-ary predicate that can't be represented in Datomic. And the advantage is that now you have a named attribute instead of something that's only defined in terms of it's position in a predicate (that turns out to be very fragile in real-world systems: think about how to change schema for something like that).