1
/* Define a Prolog predicate replicate/3 which corresponds to
 * the Haskell function of the same name, except that the numeric
 * argument is expressed symbolically.
 *
 * For example, replicate(s(s(s(0))),a,[a,a,a]) should be satisfied.
 */

So far I've come to this solution:

replicate(0,_,[]).
replicate(X,Y,[Y|Z]) :- replicate(p(X),Y,Z).

but the problem is that the s(s(s(0))) is not getting reduced by the pred function. it results into p(p(p(s(s(s(0))))))

could you guys help me out?

false
  • 10,264
  • 13
  • 101
  • 209

1 Answers1

2

This is Haskell's replicate coded with the (deprecated) n+k patterns:

replicate 0 _ = []
replicate (n+1) a = a : x where x = replicate n a

This directly corresponds to the Prolog definition:

replicate(0, _, []).
replicate(s(N), A, [A | X]) :- replicate(N, A, X).

We just move the result into the arguments list, and make it the last argument to the predicate:

    x = replicate n a    ----->     replicate(N, A, X).

The pattern matching is the same. What's not the same, is that Prolog is not an expression-oriented language. There are no expressions which get evaluated before being used as arguments in the next function call; instead, there are terms which are auto-quoted, always, used as is as arguments to predicates.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
  • 1
    ... and what's further not the same, is that `replicate(N, s(0), [A,B])` determines `N` *and* `A` and `B`. – false Aug 23 '18 at 12:51