Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog, building list with conditional clauses

I need to do this homework assignment using prolog (SWI-flavor) and cant get my head around some things.

For example, if i want to iterate through a list and add its elements to another, but ONLY if they meet certain condition, how would I go about it? I can add them all, or none, but if I add clause that checks this condition, the whole recursion turns out as "false". I understand why this is, but have no idea how to fix it. Basically what i want is:

goal(Stuff) :- do_something(X),
               only_do_this_if_something(Y),
               always_do_this(Z).

Currently, if only_do_this_if_something(Y) fails, also always_do_this(Z) doesnt happen as the whole goal turns false...

like image 521
n00bist Avatar asked May 16 '11 21:05

n00bist


People also ask

What is a clause in Prolog?

In Prolog, the program contains a sequence of one or more clauses. The clauses can run over many lines. Using a dot character, a clause can be terminated. This dot character is followed by at least one 'white space' character. The clauses are of two types: facts and rules. Facts are specified in the form of the head.

What are the elements of Prolog?

Prolog language basically has three different elements − Facts − The fact is predicate that is true, for example, if we say, “Tom is the son of Jack”, then this is a fact. Rules − Rules are extinctions of facts that contain conditional clauses. To satisfy a rule these conditions should be met.

How do you terminate a Prolog program?

In Prolog, the program contains a sequence of one or more clauses. The clauses can run over many lines. Using a dot character, a clause can be terminated. This dot character is followed by at least one 'white space' character. The clauses are of two types: facts and rules.

What are the built-in predicates in Prolog?

So there are three built-in predicates that will help us to get the results. These predicates are as follows − These three predicates take three arguments, so we have written ‘/3’ after the name of the predicates. These are also known as meta-predicates. These are used to manipulate Prolog’s Proof strategy.


2 Answers

you can use the if structure:

<condition> -> (do_something) ; (do_something else)

in this case:

goal(Stuff):-
  do_something(X),
  if_something(Y)-> do_this(Y) ; true,
  always_do_this(Z).

or you simply write two clauses like:

goal(Stuff):-
  do_something(X),
  conditional_stuff(Y),
  always_do_this(Z).

conditional_stuff(Y):-
  condition(Y),
  do_this(Y).

conditional_stuff(_).
like image 72
Thanos Tintinidis Avatar answered Oct 22 '22 02:10

Thanos Tintinidis


Check the following programming pattern, which is used quite a lot in Prolog:

  • Iterate through the list, one element at a time
  • Set a base case for the recursion
  • In one clause, check whether the conditions apply and do something, then continue with recursion
  • In the next clause skip the item and continue with recursion

You have to either use the cut (!) to forbid backtracking or explicitly check that the condition do not apply in the latter clause.

Note that you said that you wanted to have an output list with the items for which 'something' applied (which is not what you wrote in your code)...

Applying this pattern to your problem it would look something like this:

myRecursion([], []). % This is the base case
myRecursion([Item|Tail], [Item|NTail]):-
  something_applies(...),
  do_something(...),
  only_do_this_if_something(...),
  always_do_this(...).
  myRecursion(Tail, NTail).
myRecursion([Item|Tail], NTail):-
  not(something_applies(...)),
  do_something(...),
  always_do_this(...),
  myRecursion(Tail, NTail).
like image 37
gusbro Avatar answered Oct 22 '22 01:10

gusbro