Prologue, list of buildings with conditional reservations

I need to do this homework using a prologue (SWI flavor) and tilt my head over some things.

For example, if I want to iterate over a list and add its elements to another, but ONLY if they meet a certain condition, how would I do it? I can add them all or nothing, but if I add a sentence that checks this condition, all recursion is “false”. I understand why this is so, but I have no idea how to fix it. I basically want:

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) does not happen as the target's goal becomes false ...

+6
source share
4 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 just write two sentences, for example:

 goal(Stuff):- do_something(X), conditional_stuff(Y), always_do_this(Z). conditional_stuff(Y):- condition(Y), do_this(Y). conditional_stuff(_). 
+8
source

Check out the following programming pattern that Prolog uses quite a lot:

  • Iterate through the list, one item at a time
  • Set base case for recursion
  • In one sentence, check if any conditions apply and do something, then continue recursing
  • In the next section, skip the element and continue recursing

You need to either use the cut (!) To prohibit backtracking, or explicitly verify that the condition does not apply in the last section.

Please note that you said that you want to have an output list with elements for which "something" is applied (this is not what you wrote in the code) ...

Applying this template to your problem will 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). 
+1
source

If I understand correctly, then you need a predicate like include/3 :

 include(:Goal, +List1, ?List2) Filter elements for which Goal succeeds. True if List2 contains those elements Xi of List1 for which call(Goal, Xi) succeeds. 

Usage example:

 ?- include(number, [a(b), 2, _, 1.2, C, '1'], L). L = [2, 1.2]. 

Now your homework will become "how to implement include/3 " After you have implemented your version of include/3 , you can check if it matches the SWI version by looking at its source code: listing(include) .

+1
source

try the ignore / 1 predicate:

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

ignore / 1 raises a single argument and succeeds whenever it fails or not:

 ignore(X) :- X, !. ignore(_). 
0
source

Source: https://habr.com/ru/post/888264/


All Articles