views:

123

answers:

2
+1  Q: 

Prolog Question

hill(+IntList) succeeds if IntList consists of monotonically increasing integers followed by monotonically decreasing integers. For example, [1,2,5,8,11,6,3,-1] is a hill, but [1,2,5,8,11,6,9,3,-1] and [1,2,3,4,5,6] are not hills. You may assume that IntList contains only integers.

This is what i have done so far.

hill(List) :-
 increasing(List), decreasing(List).

increasing([H|Tail]) :-
 sm(H,Tail),
 increasing(Tail).
increasing([]).


decreasing([H|Tail]) :-
 gr(H,Tail),
 decreasing(Tail).

decreasing([]).

hill([]).

gr(X,[H|Tail]) :- X>H.
gr(X,[]).

sm(X,[H|Tail]) :- X<H.  
sm(X,[]).

But this doesnt work. The logic is : A list of numbers is hill IF it s increasing and then decreasing. How do i say that? This one does increasing and decreasing. which no list is both increasing and decreasing.

Any ideas?

A: 
hill(L1) :- concatenate(L2,L3,L1), inc(L2), dec(L3).
dec([X|[Y|[]]]) :- X > Y.
dec([X|[Y|L]]) :- X > Y, dec([Y|L]).
inc([X|[Y|[]]]) :- Y > X.
inc([X|[Y|L]]) :- Y > X, inc([Y|L]).
concatenate([],L2,L2).
concatenate([X|L1],L2,[X|L3]) :- concatenate(L1,L2,L3).

This works :)

But in this case even hill([1,2,3,4,5]) is a hill which it shouldnt be.
See if my edited answer helps.
bcat
This definitely works.
Yeah, that looks good. One thing though: you just rewrote `append/3`, but your prof. said you could use the predefined version. :)
bcat
Actually, you might still have a problem. Is `[1, 2, 1]` supposed to be a hill? I couldn't tell from your description. Also, your latest code can give two solutions, which may not be what you want.
bcat
true. I m just speechless:)
+2  A: 

I don't want to give a complete, working solution to a homework problem, but I'll describe in words how I would proceed from the code you've got right now. Right now your increasing and decreasing predicates test the entire list. By your definition, though, a hill is neither entirely increasing nor entirely decreasing. I would modify these predicates to have two arguments instead of one. The additional argument would be bound to the tail of the list which is not does not satisfy the increasing/decreasing criteria. Then, I'd modify hill slightly to use the new argument of increasing to test decreasingness not of the entire list, but of the portion after the initial increasing subsequence. Finally, I would use the new argument of decreasing to verify that there are no non-decreasing elements after the decreasing subsequence.

If you need better hints, or if I seem to be talking nonsense (quite possible as I'm not that good with Prolog), just let me know and I'll try to clarify more.

Edit based on OP's comments: Alright, let's try something else. L is a hill if and only if L is a list of at least two monotone increasing elements ending with some element M, followed by a list of at least one monotone decreasing element starting with some element N, where N < M. Can you translate that description to Prolog clauses?

Edit take two (SPOILER WARNING):


In your revised code, drop these three predicates: increasing([])., hill([])., and hill(List) :- decreasing(List).. This will almost give you a solution, but it will still fail, e.g. on [3, 2, 1]. Fixing this should be fairly easy, though.

bcat
Cant have two arguments that s not how Prof, wants it. Anyways, i got it, just need to fix it a little. Thanks.
Really? You can't make `increasing/1` and `decreasing/1` into `increasing/2` and `decreasing/2`? Hmm, that makes it a bit harder. Let me think...
bcat