Generate list in place of 'false'

Viewed 54

This post is about prolog programming in general, not specific to swi-prolog.

floor_locations([ 0.0, 0.17, 0.33, 0.5, 0.67, 0.83, 1.0 ]).
    
cabin_location_is_reached( cabin_location, floor_location, true ) :-
   abs( cabin_location - floor_location ) =< 0.01.
cabin_location_is_reached( cabin_location, floor_location, false ) :-
   abs( cabin_location - floor_location ) > 0.01.
    
list_floors_to_be_served( [], [],_, [] ).
list_floors_to_be_served( 
   [request|floor_requests],
   [floor_location|floor_locations],
   cabin_location,
   [has_to_be_served|floors_to_be_served_list] ) :-
   cabin_location_is_reached( 
      cabin_location,
      floor_location,
      has_to_be_served ),
   list_floors_to_be_served(
      floor_requests,
      floor_locations,
      cabin_location,
      floors_to_be_served_list ).

The question is:

list_floors_to_be_served( 
   [ false, false, true, false, false, false, true ], 
   floor_locations, 
   0.33,
   X ).

And the expected result should be:

[false, false, false, false, false, false, true]

The current result is: false :-(

How to correct my mistakes?

1 Answers

As commented by David Tonhofer, this programme has no variables. It has other errors such as: (a) in the request, the variable "floor_locations" has no value. After some detective work, here it is:

floor_locations([ 0.0, 0.17, 0.33, 0.5, 0.67, 0.83, 1.0 ]).
    
cabin_location_is_reached( Cabin_location, Floor_location, true ) :-
   abs( Cabin_location - Floor_location ) =< 0.01.
cabin_location_is_reached( Cabin_location, Floor_location, false ) :-
   abs( Cabin_location - Floor_location ) > 0.01.
    
list_floors_to_be_served( [], [],_, [] ).
list_floors_to_be_served( 
   [Request|Floor_requests],
   [Floor_location|Floor_locations],
   Cabin_location,
   [Has_to_be_served|Floors_to_be_served_list] ) :-
   
   cabin_location_is_reached(Cabin_location, Floor_location, Has_to_be_served),
   
   list_floors_to_be_served(Floor_requests, Floor_locations, Cabin_location,
      Floors_to_be_served_list).
      
go(X) :- 
    floor_locations(Ls),
    list_floors_to_be_served( 
       [ false, false, true, false, false, false, true ], Ls, 0.33, X).

I defined the go/1 predicate to retrive the floor_locations parameters needed in the call list_floors_to_be_served/4. The first argument to list_floors_to_be_served/4 is not used at all. And the given request returns:

?- go(X).
X = [false,false,true,false,false,false,false]

To get X = [false, false, false, false, false, false, true], you need to redefine :

floor_locations([ 0.0, 0.17, 0.33, 0.5, 0.67, 0.83, 0.33 ]).

Quite a curious program.

Related