Martin Kunze
Martin Kunze

Reputation: 1055

Prolog: Initialize predicate variables connected with operators correctly

I created some predicate similar to that one in the (hopefully) minimal example I want to give you below. With that I wish to get the set Z in following logical way:

Given some universal set {peter, sandra} and some binary operator l and x (l stands for is love and x for equivalent) and some basic axioms (in form of variables), say

I now want to list all axioms which fully explain some specific one illustrated by our set and save the list of them in some variable. For that purpose I generated the predicate

find_axioms(Specific, BaseSet, Fullfill)

Aim:

The BaseSet is our list of possible axioms [A l A, (B l A) x (A l B)] The Variable Fullfill should be some return-code, say Z And Specific is some set of love-relations to checked by axioms, say e.g. [peter l anna, peter l peter].

Now if I these three arguments, say I call

find_axioms([(peter l anna), (peter l peter)], [(A l A), (B l A) x (A l B)], Z).

my expected output should be:

A = peter
Z = peter l peter

axiom (B l A) x (A l B) should not be part of that cause this template is not in our variable Specific, so it can be ignored in Z.

Now I tried to explain that with following statement of logic:

∀ x in Specific: x in BaseSet → x in Fullfill

I now expected, the code should be like that:

:-op(900, xfy, l).
:-op(900, xfy, x).


find_axioms(Specific, BaseSet, Fullfill) :-
    forall(member(X, Specific), 
        (member(X, BaseSet) -> member(X, Fullfill))).

But for some reason

find_axioms([(peter l anna), (peter l peter)], [(A l A), (B l A) x (A l B)], Z).

only gives output false and does not define the variables in the way I would expect. Some syntax like

(A l A) = (peter l peter)

instead gives me the correct output I expect:

A = peter

Upvotes: 0

Views: 165

Answers (1)

slago
slago

Reputation: 5519

The predicate forall/2 is good to prove a relation or to produce some side effects (for example, when used with write/1 or assertz/1). If you intend to create variable bindings, this predicate is inadequate (since it does not change any variable binding). Instead, you should use the predicate findall/3 (see also bagof/3 and setof/3).

Thus, I think you can try something like this:

find_axioms(Specific, BaseSet, Fullfill) :-
    findall(X, 
            ( member(X, Specific), 
              member(X, BaseSet) ), 
            Fullfill).

Upvotes: 1

Related Questions