# Sets of rules as conjunctions and/or disjunctions

**URL:** https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779
**Category:** General
**Created:** [August 5, 2026, 10:24am UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779 "2026-08-05T10:24:51Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)
#### Post date: [August 6, 2026, 8:44pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/21 "2026-08-06T20:44:42Z")

</div>

Another data point from “The Art of Prolog”, pp.11:

> Logic programs can incorporate alternative definitions, or more technically disjunction, by having alternative rules, as for _parent_ :  
> parent(X,Y) ← father(X,Y) .  
> parent(X,Y) ← mother(X,Y) .

---

<div class="post-metadata">

### Author: ![herme](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@herme](https://swi-prolog.discourse.group/u/herme)
#### Post date: [August 6, 2026, 11:27pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/22 "2026-08-06T23:27:20Z")

</div>

> [@stassa.p](#):
>
> I don’t remember seeing the Gallier book before. Thanks for the links. Btw is the University of Madrid still teaching Prolog or did it give up like many others?

We still teach a semester of logic in first year and then a semester of logic programming and constraint programming in third year. I think the places that have given up on Prolog and even on logic are the ones that tend to follow fads, etc. There are only a handful of programming paradigms, with logic programming being the most different one from the others, and many top places still understand that a computer scientist is simply not complete without learning about logic programming (the same as with functional programming). I hope the relevance of Prolog and (C)LP will only increase with the growing relevance of neurosymbolic computing.

Btw, teaching (constraint) logic programming / Prolog to CS students that are already very capable with imperative programming has some challenges, but our students systematically tell us that the course widens their programming horizons. If all this is interesting for you, some of our experiences are reflected in a few papers, e.g., _[Some Thoughts on How to Teach Prolog](https://cliplab.org/papers/TeachingProlog-PrologBook.pdf), in_ Prolog - The Next 50 Years, Springer LNCS 13900, July 2023, or _[Teaching Pure LP with Prolog and a Fair Search Rule](https://ceur-ws.org/Vol-3799/paper2PEG2.0.pdf)._ Proc. 40th ICLP Workshops, [CEUR-WS.org](http://CEUR-WS.org), Vol. 3799, October 2024. Also, the [Prolog Education group](https://prolog-lang.org/Education/Education.html) organizes workshops, online discussions, and meetings related to teaching Prolog.

---

<div class="post-metadata">

### Author: ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)
#### Post date: [August 7, 2026, 12:00pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/23 "2026-08-07T12:00:46Z")

</div>

> [@herme](#):
>
> `^ ( p([]) ) ^`

OK, so:

```prolog
p([]).

```

… is a _conjunction_ when considered as part of the **program** logic (because it is in the list of predicates in the program), and is a _disjunction_ when considered at **runtime** (executable alternative).

A Programmer is naturally going to view it as a disjunction.

I view this _conjunction vs disjunction_ as being different to a declarative vs procedural reading of the program:

- Declarative reading: Are constraints defined sufficiently
- Procedural reading: Will the program execute correctly, in a timely manner, without falling into infinite loops etc.

---

<div class="post-metadata">

### Author: ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)
#### Post date: [August 7, 2026, 3:34pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/24 "2026-08-07T15:34:50Z")

</div>

> [@brebs](#):
>
> Is it correct to call this a contradiction? (I assume not, but have no idea.)

Yes, because the LHM is defined as the unique, least Herbrand model of a logic program. The existence of a smaller HM would contradict this definition.

> [@brebs](#):
>
> I think this means that the program logic could be expressed in more than one way, having different arrangements of conjunctions and disjunctions. That’s fair enough.

> [@brebs](#):
>
> I view this conjunction vs disjunction as being different to a declarative vs procedural reading of the program:
> 
> Declarative reading: Are constraints defined sufficiently  
> Procedural reading: Will the program execute correctly, in a timely manner, without falling into infinite loops etc.

What I’d say is that whereas a logic program is formally a conjunction of definite clauses and the language was designed with that semantics in mind (as noted by @herme above with respect to CNF) it is often interpreted as a disjunction because of the way that observing program execution makes it look like rules are executed similar to a series of conditional jumps or the cases of a switch statements in an imperative language.

That’s what I mean by he “procedural interpretation” or “procedural reading”. I mean it literally: because it follows from observing the execution of the program while holding in mind a model of program execution in a procedural language. Or in other words we use our understanding of how a program in a procedural language works to understand how a Prolog program works.

I don’t think that’s a mistake btw, but I think it’s useful to understand the formal semantics also.

---

<div class="post-metadata">

### Author: ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)
#### Post date: [August 7, 2026, 3:55pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/25 "2026-08-07T15:55:40Z")

</div>

> [@ridgeworks](#):
>
> Also note the [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) doc for [;/2](https://www.swi-prolog.org/pldoc/doc_for?object=%3B/2 "Disjunction (or).") does define it as disjunction, as does the ISO standard (Sect 7.8.6), so it does seem to be pretty well entrenched in Prolog. You might deem that incorrect based on some meta-interpretation of a Prolog program, but I think you’re swimming upstream

Sorry, that’s not what I meant. What I was saying is that in The Craft of Prolog the only thing called a “disjunction” is the ;/2 built-in. The book never calls a set of clauses a disjunction nor refers to them as alternatives. Of course ;/2 should be used as a disjunction operator. No problem with that, nor does it go against anything I said to have an explicit disjunction operator. On the contrary.

> [@ridgeworks](#):
>
> Logic programs can incorporate alternative definitions, or more technically disjunction, by having alternative rules, as for _parent_ :  
> parent(X,Y) ← father(X,Y) .  
> parent(X,Y) ← mother(X,Y) .

Well… that idea came from _somewhere_ didn’t it? I wouldn’t bother with it if it wasn’t so wide-spread. I don’t know if this originated with Sterling and Shapiro. It’s worth trying to find them and ask them about it.

But I think Sterling and Shapiro were just doing like everyone else and trying to make Prolog easier to understand by presenting it in terms more familiar to programmers. I don’t know much about Sterling but Shapiro in particular should be well aware of the formal definition of a set of clauses as a CNF formula.

Or not, I don’t know. After all logic programming is obviously a discipline with a root in both logic and programming. There’s going to be different views on it from different people in the community.

I’m myself trying not to say what is right and what is wrong because I don’t want to be bullish about it. The formal interpretation I note that a set of definite clauses is a conjunction should really not be controversial I mean it’s in the books. It’s just not the books on Prolog. I guess the bottom line is Prolog _programmers_ don’t really care? Only prolog _logicians_ care? And those few of us who live in between the two worlds must forever suffer from cognitive dissonance 😅

---

<div class="post-metadata">

### Author: ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)
#### Post date: [August 7, 2026, 4:00pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/26 "2026-08-07T16:00:59Z")

</div>

> [@herme](#):
>
> I think the places that have given up on Prolog and even on logic are the ones that tend to follow fads, etc.

Preach it padre! 😄

> [@herme](#):
>
> Btw, teaching (constraint) logic programming / Prolog to CS students that are already very capable with imperative programming has some challenges, but our students systematically tell us that the course widens their programming horizons. If all this is interesting for you, some of our experiences are reflected in a few papers, e.g., _[Some Thoughts on How to Teach Prolog](https://cliplab.org/papers/TeachingProlog-PrologBook.pdf), in_ Prolog - The Next 50 Years, Springer LNCS 13900, July 2023, or _[Teaching Pure LP with Prolog and a Fair Search Rule](https://ceur-ws.org/Vol-3799/paper2PEG2.0.pdf)._ Proc. 40th ICLP Workshops, [CEUR-WS.org](http://CEUR-WS.org), Vol. 3799, October 2024. Also, the [Prolog Education group](https://prolog-lang.org/Education/Education.html) organizes workshops, online discussions, and meetings related to teaching Prolog.

Thanks, the subject is indeed of great interest to me. I’ll have a look.

---

<div class="post-metadata">

### Author: ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)
#### Post date: [August 7, 2026, 5:11pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/27 "2026-08-07T17:11:17Z")

</div>

> [@stassa.p](#):
>
> I guess the bottom line is Prolog _programmers_ don’t really care?

I think many do care but they want a semantics that’s consistent with their understanding of the programming language they’re using. So given the query `?- fruit(X).`, `X` is unified with a specific fruit, not the set of all fruit. In my non-logician mind, that’s “consistent” with disjunction in first order logic. But then I’m not trying to understand a Prolog program in any other way than how Prolog itself understands it and doing so doesn’t help me.

You may be interested in taking Prolog syntax and defining a different (second order?) semantics. Perhaps disjunction disappears because it’s absorbed into the concept of sets (a disjunction of values). That’s fine if it helps you accomplish whatever you’re trying to do, but I do think it is contrary to established Prolog programming practice and needs to be incrementally built from the ground up so us non-logician Prolog programmers can understand what you’re proposing.

Now there are a few “standard predicates” for building sets (`findall` and friends). From “The Art of Prolog”, chap. 17.

> This chapter in contrast shows programming techniques that are missing from the basic logic programming model, but can nonetheless be incorporated into Prolog by relying on language features outside of first - order logic . These techniques are called second-order, since they talk about sets and their properties, rather than about individuals .

If every query was wrapped in a `findall` (or friend), then the interpretation of “Sets of rules as conjunctions..” (IMO) would be easier to comprehend:

```prolog
?- findall(X,fruit(X),SetOfFruit).
SetOfFruit = [apple, banana, durian].

```

Perhaps you can’t tell whether a “Set of Rules” is a conjunction or a disjunction just looking at the rules; it depends on how they are used (pure Prolog/ backtracking or extended Prolog/`findall`). So, in the context of this forum, what was the objective in asking the original question?

---

<div class="post-metadata">

### Author: ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)
#### Post date: [August 8, 2026, 10:00am UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/28 "2026-08-08T10:00:00Z")

</div>

> [@ridgeworks](#):
>
> I think many do care but they want a semantics that’s consistent with their understanding of the programming language they’re using. So given the query `?- fruit(X).`, `X` is unified with a specific fruit, not the set of all fruit. In my non-logician mind, that’s “consistent” with disjunction in first order logic. But then I’m not trying to understand a Prolog program in any other way than how Prolog itself understands it and doing so doesn’t help me.

I think it’s the other way around. The problems begin when programmers try to understand Prolog by falling back to the semantics of procedural languages like we’re used to. Prolog is not a procedural language, its semantics are those of predicate logic (with some differences; e.g. see the first/second order thing I discuss below) and in FOL a set of definite clauses, or, really, any set of clauses, is a conjunction of disjunctions as in Conjunctive Normal Form (CNF). That’s the theoretical basis of Prolog and there’s nothing that can be done to drastically change it without inventing a new logical paradigm from the ground up.

So it’s not that I would have to define a new semantics. It’s the actual semantics I care about. The issue is that learning Prolog has gone a certain way historically and that’s also very hard to come back from now. If The Art of Prolog says that a set of clauses is a disjunction, that’s what everyone who reads the book and who doesn’t know about CNF (which btw I don’t think is in the book) will learn. Then that gets very hard to unlearn.

> [@ridgeworks](#):
>
> Now there are a few “standard predicates” for building sets (`findall` and friends). From “The Art of Prolog”, chap. 17.

Strange but the Second-Order Programming chapter in my copy of TAoP is chapter 16, not 17.

I don’t know why S&S say setof/3 etc have to do with second-order logic. Normally, when we talk about the second-order of logic we mean that quantifiers can range over the sets of predicate and function symbols, not only the set of first-order terms. [EDIT: what I mean is that FOL too works with “sets and their properties”, not just second-order logic.]

But that distinction only makes sense in predicate logic where there are such things as sets of predicate and function symbols. In Prolog we only have “functors” which can be used anywhere in a Prolog “term” (and I put that in quotes because even the definition of a “term” is different in Prolog and logic). So for example, as I pointed out above `p(X,p(X, Y)) :- a, b, c.` is perfectly valid Prolog but it is not valid FOL because the symbol “p” can’t be both the symbol of a term and its argument.

In _second_ order logic, `p(X,p(X,Y)) :- a, b, c.` _is_ perfectly fine because then “p” is obviously a predicate symbol and “p(X,Y)” is an atomic formula passed as an argument to (a different instance of) itself. Not a problem there at all.

All of which tells us that Prolog is already … well, not second order exactly but certainly not first order. And yet, every Prolog textbook will tell you that Prolog is a language with the syntax of first-order logic. That’s just not true.

So why do textbooks do that?

Here’s my best guess: Prolog is already extreme demanding on the programmer’s mind. I know this well myself, I struggled endlessly as an undergraduate trying to learn it. Why make things even harder by introducing complicated concepts like the different orders of logic? And, let’s be fair, while there is a lot of knowledge on FOL, the further you move up in the orders of logic, the harder it gets to find both authoritative information and common understanding. Second Order Logic, eh, OK, you can find stuff about it here and there. Third Order and beyond? Forget about it. So I think people just fudge and simplify - maybe sometimes also to make it easier for themselves to understand the material that they want to teach.

> [@ridgeworks](#):
>
> So, in the context of this forum, what was the objective in asking the original question?

Well, I was hoping that if there exists a forum on the internet where a deep and informed discussion on Prolog semantics can be had, it would be this one or the ILP Discord server where I first raised this issue.

I like having deep and informed discussions on Prolog. Sue me, I don’t know. Maybe some people think that’s just aimless faffing about? But to me, because I’m also an ILP researcher as well as a Prolog programmer, the knowledge I got from discussions like that has been indispensible and I would not have been able to advance in my discipline without it.

I used to complain to my thesis advisor that he had it good when he was doing his PhD because he could go down the corridor and speak to all the greats of symbolic AI most of which are now retired. That’s… part of the reason I’m talking about this stuff here. I’m just starved for good conversations on Prolog, logic and ILP.

It’s inevitable when there’s so few of us left.

---

<div class="post-metadata">

### Author: ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)
#### Post date: [August 8, 2026, 12:46pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/29 "2026-08-08T12:46:12Z")

</div>

> [@stassa.p](#):
>
> a forum on the internet where a deep and informed discussion on Prolog semantics can be had

Perhaps [https://discourse.prolog-lang.org/](https://discourse.prolog-lang.org/)

> [@stassa.p](#):
>
> Prolog is already extremely demanding on the programmer’s mind.

Yes, when going through the learning process 😀

---

<div class="post-metadata">

### Author: ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)
#### Post date: [August 8, 2026, 3:12pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/30 "2026-08-08T15:12:57Z")

</div>

> [@stassa.p](#):
>
> Well, I was hoping that if there exists a forum on the internet where a deep and informed discussion on Prolog semantics can be had, it would be this one or the ILP Discord server where I first raised this issue.

While I’m probably not the right person to partake in the discussion, let me try to expand on my previous post.

Taking the `fruit` example, it’s just a predicate (relation?) defined by a set of clauses (facts/rules) defining what is true. If you want to view this a conjunction, which defines what a fruit is in the context of the program, that’s fine. But isn’t it incomplete in terms of the semantics, which is also dependent on the question which isn’t part of the program?

For example, if I ask the question `?- fruit(X).` the relation `fruit/1` implies that `X=apple ; X=banana ; X=durian`, i.e. a disjunction. If I ask the question `?- findall(X,fruit(X),S).`, `S` is a list of all fruit (which could mean a set). If I ask the question `?- fruit(X),fruit(Y).` the “answer” is a disjunction of conjunctions. So what did the original `fruit/1` predicate “mean”, if not all of those things.

And from the outside, the semantics isn’t any different than if I had defined `fruit/1` as:

```prolog
fruit(X) :- X = apple ; X = banana ; X = durian.

```

The semantics is the same (isn’t it?) but I suggest the argument that it’s a conjunction isn’t very compelling. Calling it anything but a predicate/relation seems like overreach.

Personally speaking, I stopped thinking much about these things several (too many?) decades ago. It is what it is, and I don’t find basic Prolog particularly confusing once unification and backtracking are mastered. In fact if one could unlearn imperative programming, it’s pretty simple (IMO). But then I’m not a logician, or even a mathematician.

---

<div class="post-metadata">

### Author: ![herme](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@herme](https://swi-prolog.discourse.group/u/herme)
#### Post date: [August 8, 2026, 3:38pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/31 "2026-08-08T15:38:45Z")

</div>

I think both the declarative and operational views are very useful and should both be taught. This is one of the arguments of the papers I mentioned above on teaching Prolog. The declarative view gives us the incredible beauty of the Prolog language: I think something important is lost if we just teach the operational view without making the student experience the beauty of clear and succinct specifications that ‘run’ in all directions, types and properties that can also be generators of tests (“inhabitants”), specifications that can be evolved into very efficient algorithms, etc. At the same time the operational semantics helps us understand termination and cost, which are necessary concerns in a real programming language (v.s. just a problem representation tool), as Prolog is, and plainly lets us use Prolog exactly the same as any other language, but with powerful additional mechanisms, which is also useful at times. Prolog can be seen as both an executable specification language and a sort of “improved Python with backtracking and unification”, and for me at least the fact that both views can coexist makes the language even more powerful and attractive.

---

<div class="post-metadata">

### Author: ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)
#### Post date: [August 8, 2026, 5:49pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/32 "2026-08-08T17:49:41Z")

</div>

> [@ridgeworks](#):
>
> Taking the `fruit` example, it’s just a predicate (relation?) defined by a set of clauses (facts/rules) defining what is true. If you want to view this a conjunction, which defines what a fruit is in the context of the program, that’s fine. But isn’t it incomplete in terms of the semantics, which is also dependent on the question which isn’t part of the program?

No, that’s the point. A definite logic program is defined as a set of definite program clauses i.e. rules and facts. Prolog goals/queries are not program clauses they are… goals.

And a set of definite clauses is a conjunction. That’s the correct semantics and that should not be controversial. The procedural interpretation comes in later when we execute the program.

But, see, in that case, too, declaratively speaking we have a conjunction. Because we are trying to prove that the conjunction of the program clauses and the goal is unsatisfiable.

> [@ridgeworks](#):
>
> And from the outside, the semantics isn’t any different than if I had defined `fruit/1` as:
> 
> ```prolog
> fruit(X) :- X = apple ; X = banana ; X = durian.
> 
> ```

But that’s a different thing now isn’t it? Here you have a disjunction between a set of Prolog atoms (FOL constants) in the body of a clause.

Whereas here:

```prolog
fruit(apple).
fruit(banana).
fruit(durian).

```

you have a set of facts. Yes, if you query both definitions with `fruit(X)` you’ll see the same results at the top-level but you’ll get those results for different reasons and in different ways. We want to know what the difference is, no?

So just to be clear again what I’m saying is that _a set of definite clauses is a conjunction_. Not that the set of bindings of a variable at the top-level is a conjunction.

It’s a subtle difference because when you get the bindings of a variable at the top-level what Prolog is really saying is “if you bind this variable that way in your goal, you get a true fact”. So when you see `X = apple` in here:

```prolog
?- fruit(X).
X = apple

```

That means that there is a fact `fruit(apple)` that is a logical consequnce of your program. Or, in other words, `fruit(apple)` is a member of a model of your program. And that model is a set of facts that are _all_ true according to your program. And because all those facts are true, no exceptions, they can be seen as a conjunction.

And I agree that you can also see the bindings of the variables as a disjunction, but what I’m arguing is that you can’t only see it that way. I think you’re wrong to stick to one interpretation only because that’s not going to give you the whole story. “It’s just a disjunction” is not the complete view.

---

<div class="post-metadata">

### Author: ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)
#### Post date: [August 8, 2026, 5:51pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/33 "2026-08-08T17:51:51Z")

</div>

> [@stassa.p](#):
>
> > [@ridgeworks](#):
> >
> > And from the outside, the semantics isn’t any different than if I had defined `fruit/1` as:
> > 
> > ```prolog
> > fruit(X) :- X = apple ; X = banana ; X = durian.
> > 
> > ```
> 
> But that’s a different thing now isn’t it? Here you have a disjunction between a set of Prolog atoms (FOL constants) in the body of a clause.

To be fair, you can also see the atoms in your disjunction as a set of facts. However `apple`, as a 0-arity fact, is a different fact than `fruit(apple)`.

---

<div class="post-metadata">

### Author: ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)
#### Post date: [August 8, 2026, 6:04pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/34 "2026-08-08T18:04:56Z")

</div>

> [@stassa.p](#):
>
> declaratively speaking we have a conjunction

I think we need clearer [terms](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/23) 😀

I view “declarative” as “Are constraints defined sufficiently” - this is the “beauty of clear and succinct specifications that ‘run’ in all directions” as @herme mentioned.

So, “declarative” to my mind is declaring constraints, rather than involving nth-order logic and getting back into the disjunction vs conjunction viewpoints (both viewpoints are equally valid, they are just from different perspectives).

Looks like we need unambiguous terms to describe:

- conjunction viewpoint
- “Are constraints defined sufficiently” whilst in the disjunction viewpoint

---

<div class="post-metadata">

### Author: ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)
#### Post date: [August 8, 2026, 8:02pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/35 "2026-08-08T20:02:55Z")

</div>

> [@stassa.p](#):
>
> And a set of definite clauses is a conjunction. That’s the correct semantics and that should not be controversial.

I’m afraid you’re losing me here. If it isn’t controversial, then why has this thread gone beyond 30 posts?

So why is a set of clauses with the same functor/arity a conjunction and what is it a conjunction of (pardon the dangling participle)? I don’t think you’re saying that a prolog program (the “knowledge base”) is just a conjunction of all its clauses (that’s what it would “mean” to a Prolog loader/compiler), are you?.

> [@stassa.p](#):
>
> > [@ridgeworks](#):
> >
> > And from the outside, the semantics isn’t any different than if I had defined `fruit/1` as:
> > 
> > ```prolog
> > fruit(X) :- X = apple ; X = banana ; X = durian.
> > 
> > ```
> 
> But that’s a different thing now isn’t it? Here you have a disjunction between a set of Prolog atoms (FOL constants) in the body of a clause.

And I see it as a disjunction of unifications, but how is the semantics/meaning different? What (non-meta) goal could distinguish between the two implementations?

> [@stassa.p](#):
>
> Yes, if you query both definitions with `fruit(X)` you’ll see the same results at the top-level but you’ll get those results for different reasons and in different ways.

But how is that relevant to the discussion? Aren’t we talking about semantics rather than process?

> [@stassa.p](#):
>
> We want to know what the difference is, no?

Do we? Why?

> [@stassa.p](#):
>
> And that model is a set of facts that are _all_ true according to your program.

I would state it differently. The model of the program is all the goals that can be proven with that program. I concede that’s a conjunction but I don’t see how that’s particularly useful. (In many cases, e.g., non-termination, it’s not even finite.)

> [@stassa.p](#):
>
> And I agree that you can also see the bindings of the variables as a disjunction, but what I’m arguing is that you can’t only see it that way. I think you’re wrong to stick to one interpretation only because that’s not going to give you the whole story. “It’s just a disjunction” is not the complete view.

But I don’t see how “knowing the whole story”, whatever that may be, helps me as a Prolog programmer. (Sorry, so many questions.) I guess I’m trying to understand how it helps you.

---

<div class="post-metadata">

### Author: ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)
#### Post date: [August 8, 2026, 11:09pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/36 "2026-08-08T23:09:57Z")

</div>

> [@ridgeworks](#):
>
> I’m afraid you’re losing me here. If it isn’t controversial, then why has this thread gone beyond 30 posts?

I think you’re right, this thread has grown a bit too long. Thank you and everyone else for the engaging conversation.

> [@ridgeworks](#):
>
> And I see it as a disjunction of unifications, but how is the semantics/meaning different?

You’re right of course. It’s a disjunction of =/2’s. My bad.

---

<div class="post-metadata">

### Author: ![herme](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@herme](https://swi-prolog.discourse.group/u/herme)
#### Post date: [August 8, 2026, 11:52pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/37 "2026-08-08T23:52:39Z")

</div>

To clarify the meaning of the disjunction in the body of a clause (which is definitely a disjunction) vs conjunctions of clauses, I think it may be useful to do some transformations on:

```prolog
fruit(X) :- X = apple ; X = banana ; X = durian.

```

I do it in propositional form to save typing:

```prolog
f <- a v b v d.

```

Just reversing:

```prolog
a v b v d -> f

```

We apply: p → q = ~p v q

```prolog
~( a v b v d ) v f

```

We apply De Morgan to move the negation inside the disjunction:

```prolog
( ~a ^ ~b ^ ~c ) v f

```

Distributing:

```prolog
( ~a v f ) ^ ( ~b v f ) ^ ( ~d v f )

```

Back to implications, using again ~p v q = p → q

```prolog
( a -> f ) ^ ( b -> f ) ^ ( c -> f )

```

Reversing again:

```prolog
( f <- a ) ^ ( f <- b ) ^ ( f <- d )

```

Note that here we got a conjunction of three clauses. I.e., in Prolog notation:

```prolog
f :- a. f :- b. f :- d.

```

And, if we go back to the original clause we get:

```prolog
fruit(X) :- X = apple.
fruit(X) :- X = banana.
fruit(X) :- X = durian.

```

which is the same as:

```prolog
fruit(apple).
fruit(banana).
fruit(durian).

```

Referring this back to conjunctive normal form (CNF), what happens is that the original clause with the disjunctions is not really in CNF, but Prolog allows us to write clauses like that for convenience. What we have done with the transformations above is to put the clause with the disjunction in CNF. This results in three clauses.

---

<div class="post-metadata">

### Author: ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)
#### Post date: [August 9, 2026, 9:09am UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/38 "2026-08-09T09:09:00Z")

</div>

> [@ridgeworks](#):
>
> pardon the dangling participle

No need to apologize; “dangling preposition” is a made-up rule by John Dryden (1672) and Bishop Robert Lowth (1762), who thought that a Germanic language (English) should follow Latin grammar rules (and Latin doesn’t have things like phrasal verbs or _trennbare Verben_). Even _The Economist_ – which incorrectly eschews spitting infinitives – agrees that it’s usually OK, or often preferred, to dangle prepositions.

---

<div class="post-metadata">

### Author: ![herme](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@herme](https://swi-prolog.discourse.group/u/herme)
#### Post date: [August 9, 2026, 6:24pm UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/39 "2026-08-09T18:24:26Z")

</div>

W.r.t. to the questions on queries, suppose we want to prove that there  
exist a list whose length is less than 3 (and obtain the  
solutions). In Prolog we would write:

```prolog
?- list(X), length_lt(X,3)).

```

Let’s see what this Prolog notation really means.

#### The query in logic

To write “there exists a list whose length is less than 3” directly  
in logic we can do it as follows:

```prolog
exists X ( list(X) ^ length_lt(X,3) )

```

with ^ being conjunction.

Now, in resolution (Prolog’s ‘operational’ semantics) we prove things  
by contradiction, i.e., we start by negating what we want to prove, and  
try to show that this is false (and thus that the converse is  
true). I.e., we try to prove that there do indeed exist lists whose  
lengths are less than 3. Furthermore, while doing it, and thanks to  
resolution, we even find counter examples, i.e., lists that are indeed  
of length less than 3, namely [], [\_], and [\_,\_], which are then our  
answers.

OK, so, in order to prove things, we have to negate what we want to  
prove, so, we write our query (using ~ for negation) as follows:

```prolog
~( exists X ( list(X) ^ length_lt(X,3) ) )   

```

Let’s call this expression [a].

#### Relating the two notations

But, how does [a] relate to:

```prolog
?- list(X), length_lt(X,3)).

```

It is in fact exactly the same. Let’s see it.

First, the ?- above is standing for :- . Using ‘?’ instead of ‘:’ is  
just Prolog notation reminding us that this is a query. So our query  
is really:

```prolog
:- list(X), length_lt(X,3)).

```

If we write this using logic notation we have:

```prolog
true <- list(X) ^ length_lt(X,3)).

```

reversing → :

```prolog
list(X) ^ length_lt(X,3)) -> true

```

using again p → q = ~p v q, we have:

```prolog
~( list(X) ^ length_lt(X,3) ) v true

```

equivalent to:

```prolog
~( list(X) ^ length_lt(X,3) )

```

which, is indeed [a], i.e., our query, negated. So,

```prolog
?- list(X), length_lt(X,3)).

```

is the same as [a] and represents the negation of what we want to  
prove (i.e., what we want to ‘run’).

#### What about the quantifiers?

We normally do not write quantifiers in both CNF and Prolog because  
when we convert to CNF we eliminate the existential ones, and, since  
then all variables have a forall, normally we do not write them. But  
they are there, and, in CNF, they are always the outermost thing, i.e.,

```prolog
~( list(X) ^ length_lt(X,3) )

```

is really:

```prolog
forall X ~( list(X) ^ length_lt(X,3) )

```

Moving the forall inside the negation (which changes it to an exists),  
we have:

```prolog
~( exists X ( list(X) ^ length_lt(X,3) ))

```

I.e., exactly [a].

## Is the query a Horn clause?

Finally, is our query,

```prolog
?- list(X), length_lt(X,3)).

```

equivalently:

```prolog
~( exists X ( list(X) ^ length_lt(X,3) ))

```

a Horn clause? Let’s see, we have:

```prolog
~( exists X (list(X) ^ length_lt(X,3)) )

```

If we move the quantifier outside the negation (changes to forall) we get:

```prolog
forall X ~( list(X) ^ length_lt(X,3) )

```

And, if we move the negation inside the conjunction by De Morgan we  
get:

```prolog
forall X (~list(X) v ~length_lt(X,3))

```

As usual we can drop the forall:

```prolog
~list(X) v ~length_lt(X,3)

```

Note that this is a disjunction of literals, all negated (none of them  
non-negated), which is the definition of a Horn clause of type query  
(zero non-negated literals). I.e., our query is indeed a Horn clause, and of type “query”.

---

<div class="post-metadata">

### Author: ![wlodr](https://avatars.discourse-cdn.com/v4/letter/w/dec6dc/32.png) [@wlodr](https://swi-prolog.discourse.group/u/wlodr)
#### Post date: [August 16, 2026, 8:18am UTC](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779/40 "2026-08-16T08:18:01Z")

</div>

> [@stassa.p](#):
>
> Over at the ILP Discord server there was a discussion about whether a set of Prolog rules should be seen as a disjunction or a conjunction.
> 
> The, let’s say “traditional” interpretation that one can find in many Prolog sources is that rules with the same functor/arity are a disjunction, e.g. :

I missed the whole discussion, but the answer - conjunction - seems to be obvious and indisputable.

For instance.  
A set of facts means that each fact is true: conjunction.  
The standard append program means that its fact AND it rule are true: conjunction.  
{a:-b. a:-c.} means that both rules hold: conjunction.

[Previous page](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779.md?page=1)

[Next page](https://swi-prolog.discourse.group/t/sets-of-rules-as-conjunctions-and-or-disjunctions/9779.md?page=3)
