Compound Boolean Expressions in Prolog

In Prolog, how do you implement complex logical predicates such as (A and B) or (C and D)?

This may seem like a simple question, but many of the available online tutorials are not well described in boolean terms. I assume you cannot just write:

test(A, B, C, D) :- cond(A), cond(B); cond(C), cond(D). 

so how would you do that?

+4
source share
3 answers

As others have noted, your original example

 test(A, B, C, D) :- cond(A), cond(B); cond(C), cond(D). 

completely correct (it is assumed that the analysis is the way you thought it up). Have you tried?

Primer

Logical and

 foo :- a , b . 

Logical OR

 foo :- a ; b . 

Combined

 foo :- a , b ; c , d . 

The above analysis:

 foo :- ( a , b ) ; ( c , d ) . 

Use parentheses to indicate another desired binding:

 foo :- a , ( b ; c ) , d . 

Better yet, avoid the operator ; OR and break alternatives into separate sentences. Consistency is much easier for people to understand than branching tree structures. Breaking the rotation of several articles simplifies testing / debugging and improves understanding. Therefore prefer

 foo :- a , b . foo :- c , d . 

over

 foo :- a , b ; c , d . 

and prefer

 foo :- a , bar , d . bar :- b . bar :- c . 

over

 foo :- a , ( b ; c ) , d . 

Perhaps the most important thing is to break it down into several articles, as this simplifies subsequent maintenance. With a structure like:

 foo :- a , b ; c , d . 

what do you do when you add another case? How about when it expands to 50 alternatives?

Each additional alternative increases the number of code paths through a sentence, making testing and understanding difficult. In order to get full coverage of the code during testing, it is necessary to individually inspect many alternative paths.

With equivalent structure

 foo :- a , b . foo :- c , d . 

Adding alternatives is simply a matter of adding an additional offer or offers, each of which can be tested in isolation.

A professional programmer writes first for people who within a few years after that should understand, modify and correct this code ( hint: that this person can be himself).

+19
source

A simple alternative to alliances is the use of wildcards. For disjunctions, use a few lines. Your example:

 test(A, B, C, D) :- test1(A, B). test(A, B, C, D) :- test2(C, D). test1(A, B) :- A, B. test2(C, D) :- C, D. 

What about (A or B) and (C or D)?

 other(A, B, C, D) :- other1(A, B), other2(C, D). other1(A, B) :- A. other1(A, B) :- B. other2(C, D) :- C. other2(C, D) :- D. 

Please note that this is only mentioned as an alternative to joel76.

+1
source

test (A, B, C, D): - (cond (A), cond (B)); (cond (C), cond (D)).

0
source

Source: https://habr.com/ru/post/1392180/


All Articles