2

Anyone knows how to tell Prolog that n(n(p)) and n(p) represent the same thing?

Or how to reduce n(n(p)) to n(p)?

false
  • 10,264
  • 13
  • 101
  • 209
theSongbird
  • 229
  • 1
  • 3
  • 13
  • 1
    You need to define a relation `equivalent_with/2` – false Nov 13 '19 at 11:35
  • @false Can't I define a predicate `n(n(p))` that returns `n(p)`. What I want, in fact, is that all occurrences of the within a list to be replaced with the latter. – theSongbird Nov 13 '19 at 12:06
  • 1
    Predicates don't have a return value (at best they return a boolean). You need to express the equivalence as relation between two terms: the expanded one and the reduced one. – lambda.xy.x Nov 13 '19 at 18:20

1 Answers1

3

Anyone knows how to tell Prolog that n(n(p)) and n(p) represent the same thing?

Prolog's unification system has a clear meaning of when two things are the same. n(n(p)) and n(p) are not the same thing. You can construct a predicate that defines a more generic equivalence relation than (=)/2.

Normally in Prolog two constants are different if they have a different name. Two compound terms are the same only if the functor is the same (the name of the functor and the number of parameters), and the parameters are equal as well.

We thus can define a predicate like:

equiv_(n(n(p)), n(p)).

equivalence(L, R) :-
    equiv_(L, R).
equivalence(L, R) :-
    equiv_(R, L).
equivalence(L, L).

If you the match with equivalence(n(n(p)), n(p)), it will return true.

@false Can't I define a predicate n(n(p)) that returns n(p). What I want, in fact, is that all occurrences of the within a list to be replaced with the latter.

You can make a predicate that unifies a second parameter with n(p) if the first one is n(n(p)):

replace_nnp(X, n(p)) :-
    X == n(n(p)).
replace_nnp(X, X) :-
    X \== n(n(p)).

Then we can use maplist/3 [swi-doc] to map a list of items to another list of items:

replace_nnp_list(LA, LB) :-
    maplist(replace_nnp, LA, LB).

For example:

?- replace_nnp_list([n(n(p)), p, n(p), n(n(p))], X).
X = [n(p), p, n(p), n(p)] ;
false.
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555