Prolog: How do i do if conditions?

• (2 Pages)
• 1
• 2

16 Replies - 39644 Views - Last Post: 07 October 2011 - 05:30 AMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=249036&amp;s=5ad4aaab506b5bfe577b2512f040201b&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

#1 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Prolog: How do i do if conditions?

Posted 28 September 2011 - 06:01 PM

Hi guys,

I am currently learning prolog in a principles class and I am still not understanding how to incorporate if conditions. What we are having to do is if a numeric list is sorted, what values are missing. What I am doing is checking to see if the head+1 value is a member and if it is then place that value in a separate to be printed, if not then just continue down the list. Any ideas?

(I will continue to read on this)

This post has been edited by BBird40: 28 September 2011 - 06:01 PM

Is This A Good Question/Topic? 0

Replies To: Prolog: How do i do if conditions?

#2 sepp2k

• D.I.C Lover

Reputation: 2600
• Posts: 4,153
• Joined: 21-June 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 08:57 AM

If conditions in prolog can be written as condition -> then_clause ; else_clause. If -> hasn't been introduced yet, you can instead do something like this:
```condition,
then_clause
;
negated_condition,
else_clause.

```

Or similarly:
```f(X,Y) :- condition, then_clause.
f(X,Y) :- negated_condition, else_clause.

```

#3 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 09:52 AM

Yes we are able to use ->.

I am not sure what I am missing in my function, it keeps printing false. Anyway you can put in the right direction?

```findmissing([],[]).
findmissing([L],X):- sort([L],[Y,Z|T]), J is Y+1, J =:= Z -> findmissing([Z|T],X); X=[J], findmissing([J,Z|T],X).

```

Am I doing the if-else condition incorrectly?

#4 sepp2k

• D.I.C Lover

Reputation: 2600
• Posts: 4,153
• Joined: 21-June 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 10:24 AM

Your usage of -> looks fine, but you made some other mistakes:

[L] is a list containing the single element L. So if you call findmissing([42], X)., [42] will match [L] and L will be bound to 42, but if you do findmissing([23,42],X)., [23,42] will not match [L], because [23,42] is a list with two arguments and [L) only matches lists with one element. So prolog will just return false without running any of your code. You want to just use L instead of [L].

Also the logic of your else-clause seems suspect to me - not sure what you're trying to do there. X=[J] and findmissing([J,Z|T],X) can't both be true. I mean what you want is for X to be a list which contains J followed by all the missing elements of [J,Z|T], right? So you should do something like this in your else clause instead:

```findmissing([J,Z|T],MissingElementsOfJZT),
X = [J | MissingElementsOfJZT].

```

PS: Sorting the list on each step is a bit of a waste, since you only need to sort the list once. So what I would do is write a helper function, which finds the missing elements in an already-sorted list and then make your real function call the helper function after sorting the list.

PPS: Are you sure that X is supposed to be a list? It seems to me (though I should mention that I'm no prolog expert by a long shot) that it would be more prologish to let X be a variable that can be any of the missing elements. I.e. write it so that the result of missing([1,4], X). would be X = 2; X = 3. and not X = [2,3]. Although obviously which one is better depends on what you want to do with the result.

#5 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 11:01 AM

I see what your saying about the else clause. I changed it and eliminated the recursive call. As for displaying the list, this is the intent, to display the missing elements in a list.

As for the helper function, I am actually suppose to implement that functions to test whether or not the list is sorted in ascending or descending order. The thing is I am unsure of how to check if the list is in ascending or descending order.

Here is what I got so far:

```findmissing([],[]).
findmissing([H|T],X):- sort([H|T],[Y,Z|E]), J is Y+1, J =\= Z -> findmissing([Z|T],X); X=[J].

sorted([]).
sorted([X]).
sorted([A|[B|C]]):- A =< B -> sorted([B|C]).
sorted([A|[B|C]]):- A >= B -> sorted([B|C]).

```

and for some reason, I am testing my findmissing and I am getting results like this:

?- findmissing([1,5,4],X).
X = [_G8].

I will keep working on this and if I progress further I will let you know, thanks for your help sepp.

This post has been edited by BBird40: 29 September 2011 - 11:26 AM

#6 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 11:40 AM

Ok I can get if sorted in ascending order. However, I cannot get it work for both ascending and descending. Anyway I can make 2 rules? Say if this rule does not work try this rule?

here is what I got:
```sorted([]).
sorted([X]).
sorted([A,B|C]):- A < B, sorted([B|C]).

```

Lastly, anyway I can get prolog to print yes instead of true when a list is sorted, and respectively no if not. Or are these terms true/yes and false/no 1 in the same?

This post has been edited by BBird40: 29 September 2011 - 11:41 AM

#7 sepp2k

• D.I.C Lover

Reputation: 2600
• Posts: 4,153
• Joined: 21-June 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 12:18 PM

The easiest way to make your sorted predicate work in both directions would be to rename your sorted to sorted_ascending, then create another predicate sorted_descending analogously, and simply define sorted(X) = sorted_ascending(X) ; sorted_descending(X)..

Quote

Lastly, anyway I can get prolog to print yes instead of true when a list is sorted, and respectively no if not. Or are these terms true/yes and false/no 1 in the same?

As far as I'm aware which output is used to describe success and failure is up to the implementation. I.e. some implementations print true on success and others write Yes. I don't think there's a way that you can change it except by switching to another implementation, but it doesn't really matter anyway. It's just a cosmetic difference.

#8 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 01:58 PM

Thanks for the help sepp, I am now going to work on getting that function incorporated with my findmissing. I appreciate all your help!

#9 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 02:17 PM

```findmissing([],[]).
findmissing([X],[]).
findmissing([A,B|C],X):- sorted([A,B|C]) -> D is A+1, D =\= B -> X=[D], findmissing([A+1,B|C],X); sort([A,B|C],[H|T]), findmissing([H|T],X).

```

it says I have a missing comma or bar in the last line, any ideas why?

Nevermind, I see why. Well, I am still getting an issue. I think I am going to define another function that just iterates through the list, and checks to make sure the value that is missing is in the list.

EX- [1,4,5]

Next value should be 2, if not put 2 in a list.
Next value should be 3, if not put 3 in a list.
Next value should be 4, ........

the only issue I have is going through the list, should I go backwards? and just iterate through that way? Say [1,4,5] then [1,4], then [1] but in that sense I will still miss 2 and everytime I go to make a rule with the notation findmissing[A|B,C] it tells me that the comma is an error.

Ok I don't know why I am making this hard on myself, I am just going to append the missing value to the list and call my function, it will sort the list again and eliminate the head if the value head+1 is in the list. Gonna try that.

This post has been edited by BBird40: 29 September 2011 - 02:30 PM

#10 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Re: Prolog: How do i do if conditions?

Posted 29 September 2011 - 07:10 PM

Well it looks like I have a hit a wall. I can get this to work, but it only goes through once.

```findmissing([],[]).
findmissing([X],[]).
findmissing(L,X):- sort(L,[A,B|C]), D is A+1, D =\= B -> X=[D].

```

but when I try to add more I just get false when attempting my code. Sometimes I get errors stating sort/2, variables not sufficiently instantiated. Here is what it looked like:

```findmissing([],[]).
findmissing([X],[]).
findmissing([H|T],X):- sort([H|T],[A,B|C]), D is A+1, D =\= B -> X=[D],
append([B|C],[D],[M|N]),
findmissing([M|N],X);
findmissing([H|T]).

```

Also, I tried to say if it sorted then proceed with D is A+1,...... then if not then sort the list and findmissing but that did not work either.

It has to be something after making X=[D], what am I doing wrong after this statement?

#11 sepp2k

• D.I.C Lover

Reputation: 2600
• Posts: 4,153
• Joined: 21-June 11

Re: Prolog: How do i do if conditions?

Posted 30 September 2011 - 02:38 AM

You're still doing the X=[D], ..., findmissing([M|N],X) bit. That won't work as I've explained earlier.

Also findmissing([H|T]) is wrong: a) findmissing takes two arguments and if you recurse without changing the arguments at all (you're given [H|T] and then you pass in the same [H|T] to the recursive call), it will simply loop forever (or until it's out of stack space).

Also a note regarding your earlier code (which uses sorted): You check whether the list is sorted (either ascending or descending) and sort it when it isn't. So if the list is sorted descending, you won't sort it again - however your algorithm only works when working with ascending lists, so it won't work when passing in a list that is sorted descending.

#12 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Re: Prolog: How do i do if conditions?

Posted 30 September 2011 - 03:34 PM

Ah, I see. Sorry about that Sepp. I am still trying to wrap my head around the semantics of prolog.

This is what I got so far:
```findmissing([],[]).
findmissing([X],[]).
findmissing([H|T],X):- sort([H|T],[A,B|C]), D is A+1, D =:= B -> findmissing([B|C],X); findmissing([D,B|C],D).

```

For this code I am getting an error saying that sort/2 arguments are not efficiently instantiated.

Here is what I try with sorted:
```findmissing([],[]).
findmissing([X],[]).
findmissing([H,I|T],X):- sorted([H,I|T]) -> D is H+1, D =:= I -> findmissing([I|T],X); findmissing([D,I|T],D); sort([H,I|T],L), findmissing(L,X).

```

Now this is extrememly extensive but for this I just get false. I am going to read through it and try to figure it out more. May take me awhile b/c prolog is not what I am used to but I am trying it.

#13 sepp2k

• D.I.C Lover

Reputation: 2600
• Posts: 4,153
• Joined: 21-June 11

Re: Prolog: How do i do if conditions?

Posted 01 October 2011 - 03:22 AM

I would suggest that you first try to get it to work only for lists that are already sorted. And once you've got that working you can add the call to sort. Focusing on one thing at a time tends to make things easier in my experience.

#14 BBird40

Reputation: 0
• Posts: 30
• Joined: 09-February 11

Re: Prolog: How do i do if conditions?

Posted 05 October 2011 - 11:02 PM

Well, I got it to work but for just iteration. Here it is:

```findmissing([H|T],X):- sort([H|T],[Y,Z|E]), findhole([Y,Z|E],X).

findhole([],[]).
findhole([K],[]).
findhole([H,S|T],X):- D is H+1, D =\= S -> X=[D].

```

If I put anything after the if condition it immediately changes the output to false instead of the first element that is missing.

Tried using a replace function to put D in the place of H but was having issues then calling findhole or findmissing but neither would work in successfully iterating through the list. Anyways, thanks for all the help sepp. It helped.

#15 sepp2k

• D.I.C Lover

Reputation: 2600
• Posts: 4,153
• Joined: 21-June 11

Re: Prolog: How do i do if conditions?

Posted 06 October 2011 - 03:19 AM

As I already said in the beginning, your then-case should look something like this for it to find more than one missing element:

```findhole([D,S|T],MissingElementsOfDST),
X = [D | MissingElementsOfDST].

```

Of course you're also missing your else-clause, so this would indeed always produce false until you add an appropriate else-clause.

This post has been edited by sepp2k: 07 October 2011 - 05:30 AM