Skip to content

Multiset Semantics

Logica, as well as most other logic programming languages follows multiset semantics.

That there is no ordering of rows in predicates, but each row may occur 1, or many times in the predicate.

Number of occurrences of a row is called multiplicity.

Example 1: Predicate Fruit defined with facts

Fruit("apple");
Fruit("apple");
Fruit("orange");
Fruit("banana");
Fruit("banana");
Fruit("banana");

evaluates to

+--------+
| col0   |
+--------+
| apple  |
| apple  |
| orange |
| banana |
| banana |
| banana |
+--------+

Disjunction sums multiplicities.

Example 2: Predicate OurFruit defined as

MyFruit("apple");
MyFruit("banana");

YourFruit("apple");
YourFruit("orange");

OurFruit(x) :- MyFruit(x) | YourFruit(x);

evaluates to

+--------+
|  col0  |
+--------+
| apple  |
| banana |
| apple  |
| orange |
+--------+

Conjunction multiplies multiplicities.

To illustrate the concept we will use an abstract predicate this time.

Example 3: Predicate Q defined as

Q("a", "b");
Q("a", "b");
Q("x", "y");

R("b", "t");
R("b", "t");
R("b", "t");

P(x, z) :- Q(x, y), R(y, z);

evaluates to

+------+------+
| col0 | col1 |
+------+------+
| a    | t    |
| a    | t    |
| a    | t    |
| a    | t    |
| a    | t    |
| a    | t    |
+------+------+

Multiset semantics is natural for applications.

Disjunction is anaolgous to consequent for loops while conjunction is analogous to nested loops.

For example program

C(x) :- A(x) | B(x);

acts like Python program

C = []
for x in A:
  C.append(x);
for x in B:
  C.append(x);

And program

C(x) :- A(x), B(x);

Acts like:

C = []
for x1 in A:
  for x2 in B:
    if x1 == x2:
      C.append(x1)