Search code examples
prolog

How do I rewrite the following so it uses if_?


I am doing some easy exercises to get a feel for the language.

is_list([]).
is_list([_|_]).

my_flatten([],[]).
my_flatten([X|Xs],RR) :-
   my_flatten(Xs,R),
   (is_list(X), !, append(X,R,RR); RR = [X | R]).

Here is a version using cut, for a predicate that flattens a list one level.

my_flatten([],[]).
my_flatten([X|Xs],RR) :-
   my_flatten(Xs,R),
   if_(is_list(X), append(X,R,RR), RR = [X | R]).

Here is how I want to write it, but it does not work. Neither does is_list(X) = true as the if_ condition. How am I intended to use if_ here?


Solution

  • In Prolog, the equivalen of an if … then … else … in other languages is:

    (condition -> if-true; if-false)

    With condition, if-true and if-false items you need to fill in.

    So in this specific case, you can implement this with:

    my_flatten([],[]).
    my_flatten([X|Xs],RR) :- 
        my_flatten(Xs,R),
        (  is_list(X)
        -> append(X,R,RR)
        ; RR = [X | R] ).

    or we can flatten recursively with:

    my_flatten([],[]).
    my_flatten([X|Xs],RR) :- 
        my_flatten(Xs,R),
        (  flatten(X, XF)
        -> append(XF,R,RR)
        ; RR = [X | R] ).

    Your if_/3 predicate is used for reified predicates.