Prologue: get the opposite result

I have the following code:

neighbor(C1, C2, [C1, C2|L]).
neighbor(C1, C2, [C2, C1|L]).
neighbor(C1, C2, [H|L]) :- neighbor(C1, C2, L).

not_neighbors(C5, C2, E, R) :-
    not_neighbor(C5, C2, E).

not_neighbors(C5, C2, E, R) :-
    not_neighbor(C5, C2, R).

/* THIS DON'T WORK */
not_neighbor(C5, C2, E) :-
    \+ neighbor(C5, C2, E).

Or:

same_position(I, J, [I|U], [J|V]).
same_position(I, J, [M|U], [N|V]) :-
    I \== M,   % optimisation
    J \== N,   % optimisation
    same_position(I, J, U, V).

/* THIS DON'T WORK */
not_under(C4, C1, R, E) :-
    \+ same_position(C4, C1, R, E).

I know that the problem is negation, and I want, for example, to get the opposite result same_position.

M. @CapelliC suggested I use dif/2, but I don’t know how to apply this in my specific example.

+4
source share
2 answers

Let's first think about what “neighbors” mean in the list: in what cases Aand Bneighboring elements in the list?

The answer . If the list has a form [...,X,Y,...]and at least one of the following actions is performed:

  • A = X and B = Y
  • A = Yand B = X.

: (A = X & and; B = Y) & or; (A = Y & and; B = X).

, :

  &; ((A = X & and; B = Y) & or; (A = Y & and; B = X)) & equiv;

& ; &; (A = X & and; B = Y) &; &; (A = Y & and; B = X) & equiv;

& ; (& not; A = X & or; & not; B = Y) & &; (& not; A = Y & or; & not; B = X) & equiv;

& ; (A & ne; X & or; B & ne; Y) & &; (A & ne; Y & or; B & ne; X)

, - , ?

X & ne; Y Prolog, dif/2, @CapelliC. dif/2 , . pure . Prolog , , , ! iso_dif/2, .

Prolog :

( dif(A, X) ; dif(B, Y) ), ( dif(A, Y) ; dif(B, X) )

(',')/2 , (;)/2 .

, :

not_neighbours(_, _, []).
not_neighbours(_, _, [_]).
not_neighbours(A, B, [X,Y|Rest]) :-
        ( dif(A, X) ; dif(B, Y) ),
        ( dif(A, Y) ; dif(B, X) ),
        not_neighbours(A, B, [Y|Rest]).

:

?- not_neighbours(a, b, [a,b]).
false.

?- not_neighbours(A, B, [A,B]).
false.

?- not_neighbours(A, B, [_,A,B|_]).
false.

?- not_neighbours(A, B, [_,B,A|_]).
false.

?- not_neighbours(a, b, [_,a,c,_]).
true .

, , , .

, (;)/2 , . , :

& ; A & ; B & equiv; A & rightarrow;

, (& not; A = X & or; & not; B = Y) A = X & rightarrow; B & ne; Y.

implication Prolog if_/3:

impl(A, B) :- if_(A, B, true).

:

not_neighbours(_, _, []).
not_neighbours(_, _, [_]).
not_neighbours(A, B, [X,Y|Rest]) :-
        impl(A=X, dif(B, Y)),
        impl(B=X, dif(A, Y)),
        not_neighbours(A, B, [Y|Rest]).

:

?- not_neighbours(a, b, [x,y]).
true ;
false.

:

?- not_neighbours(a, b, [X,Y]).
X = a,
dif(Y, b) ;
X = b,
dif(Y, a) ;
dif(X, b),
dif(X, a) ;
false.

. , , , :

?- length(Ls, _), not_neighbours(A, B, Ls).

, Prolog.

dif/2 , Prolog . dif/2 () , , . , , dif/2.

+3

-, \+ , semidet . - . - , \+ neighbor(...) . , :

not_neighbor(C1, C2, List) :-
    append(_, [C10,_|Postfix], List),
    member(C20, Postfix),
    swap(C1,C2, C10,C20).

swap(X,Y, X,Y).
swap(X,Y, Y,X).

. http://swish.swi-prolog.org/p/njssKnba.pl

+1

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


All Articles