Prolog - how to do setof that returns empty list instead of failing

后端 未结 3 718
臣服心动
臣服心动 2020-12-20 03:49

I need an ordered list of Objects that satisfy Goal. setof takes care of the ordering, but fails when no Objects satisfy Goal. I want to return an empty list in

相关标签:
3条回答
  • 2020-12-20 03:50

    If you do not need the potential nondeterminism or the variable-quantification features of setof, you can stick with findall/3. This is deterministic and doesn't fail:

    ?- findall(X, fail, Xs).
    Xs = []
    yes
    

    You can then sort the results yourself using sort/2:

    findall(Object, Goal, UnsortedWithDuplicates),
    sort(UnsortedWithDuplicates, List)
    
    0 讨论(0)
  • 2020-12-20 03:51

    First,

    ..., ( setof(Object, Goal, List), ! ; List = [] ), ...
    

    does not work, as you suggest. It always succeeds for List = [], and it only shows the first answer of setof/3. But setof/3 may produce several answers. The general method that works in any Prolog is:

    ..., ( \+ Goal -> List = [] ; setof(Object, Goal, List) ), ...
    

    Many implementations offer an implementation specific control construct for this which avoids that Goal is called twice. E.g. if/3 (SICStus, YAP), or (*->)/2 (SWI, GNU):

    ..., if( setof(Object, Goal, ListX), ListX = List, List = [] ), ...
    
    ..., ( setof(Object, Goal, ListX) *-> ListX = List ; List = [] ), ...
    

    The new variable ListX is necessary for the (admittedly rare) case that List is already instantiated.

    Note that both other answers do not produce exactly what you asked for.

    0 讨论(0)
  • 2020-12-20 04:06
    (setof(Object, Goal, List) ; List = [])
    

    will work as well (setof itself is deterministic).

    To be sure to get rid of the choice point, we need a bit more verbose

    (setof(Object, Goal, List) -> true ; List = [])
    

    edit as it stands, my answer is plainly wrong, or at least very incomplete. After false comments, and answer, I would suggest

    setof(Object, Goal, List) *-> true ; List = [].
    
    0 讨论(0)
提交回复
热议问题