1

Fairly new to prolog and trying to solve some exercises. Given a knowledge base of components

component(ElementX,ElementY,Qty).
ElementX uses ElementY in it's structure in quantity Qty.

component(car, door, 4).
component(car, wheel, 4).
component(wheel, tire, 1).

I want to find every ElementX that isn't an ElementY at the same time.

This is the expected result

?-final_product(X). 
X = car; 
false. 

Which leads me to believe I can't use a cut since I get this

?-final_product(X). 
X = car.

and if I don't prevent backtracking all I get is

?-final_product(X). 
X = car; 
X = car; 
false. 

How exactly would I achieve the expected result?

EDIT:

final_product(X):-
  setof(X, (component(X, _, _), \+component(_, X, _)), Results),
  member(X, Results).
false
  • 10,264
  • 13
  • 101
  • 209
idetodospoca
  • 73
  • 3
  • 12
  • 3
    Where's your code for `final_product/1`? Technically, you aren't going to "prevent backtracking" without a cut since that's exactly what a cut does. But you can use a different technique. For example, you could write a predicate that collects the solutions in a list and only include a solution in the list if it hasn't been included already. Or, you can use `setof/3` which already does that for you. – lurker Oct 08 '18 at 00:59
  • 1
    There are a lot of ways to handle this, but I think the direct way is best: enumerate your final products as facts rather than try to calculate them. After all, if this were an RDBMS, this would be like a foreign key to a table that doesn't exist: you'd be missing an entity here, and trying to reconstruct it by looking at the related entities is going to be less efficient than just having the entity. IME you eventually wind up needing that entity anyway. – Daniel Lyons Oct 08 '18 at 04:40
  • I've edited my comment with the code for final_product using setof/3 but I still get all the results – idetodospoca Oct 08 '18 at 11:22
  • You're not using `setof/3` correctly: `setof(X, Y^N^(component(X, Y, N), \+component(_, X, _)), Results)` – lurker Oct 08 '18 at 11:37
  • Thank you, that did it. Wasn't sure how to properly use the infix '^'. – idetodospoca Oct 08 '18 at 12:32
  • The `^` syntax is a feature of `setof/3` (and `bagof/3`), not Prolog in general. You're saying you consider `Y` and `N` to be _existentially quantified_, essentially they are dependent on the other variables of the term and not interesting as far as matching goes. `findall/3` can be easier for beginners because it will only ever produce a single solution, so it acts as though all the other variables are existentially quantified. – Daniel Lyons Oct 08 '18 at 16:37

0 Answers0