# Erroneous, failure, semidet, det, multi

**URL:** <https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607>\
**Category:** Help!\
**Created:** [May 3, 2019, 3:40pm UTC](https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607 "2019-05-03T15:40:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![gavin.mendel.gleason](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gavin.mendel.gleason/32/207_2.png) [@gavin.mendel.gleason](https://swi-prolog.discourse.group/u/gavin.mendel.gleason)\
**Post date:** [May 3, 2019, 3:40pm UTC](https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607/1 "2019-05-03T15:40:58Z")

</div>

I have the following program which does a run-time check of various determinacies. I believe they all work, but the version of multi has a seemingly unnecessary additional call. Is there some way to avoid this?

```
errorneous(Module,Goal) :-
    throw(determinism_error(Module:Goal,erroneous)).

failure(Module,Goal) :-
    call(Module:Goal),
    throw(determinism_error(Module:Goal,failure)).

det(Module,Goal) :-
    ( call_cleanup(Module:Goal, Det=true),
        ( Det == true
        -> true
        ; throw(detreminism_error(Module:Goal, det))
        )
    -> true
    ; throw(detreminism_error(Module:Goal, det))
    ).

semidet(Module,Goal) :-
    ( call_cleanup(Module:Goal, Det=true),
        ( Det == true
        -> true
        ; throw(detreminism_error(Module:Goal, semidet))
        )
    -> true
    ; fail
    ).

    
multi(Module,Goal) :-
    ( \+ call(Module:Goal)
    -> throw(determinism_error(Module:Goal,multi))
    ; call(Module:Goal)
    ).
```

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [June 11, 2019, 6:11pm UTC](https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607/2 "2019-06-11T18:11:44Z")

</div>

You have a few typos (e.g., “detreminism” instead of “determinism”).  
Also, it’s better to do a throw like this: `throw(error(determinism_error(Module:Goal, multi), _))` so that you can get some nice default handling, e.g., displaying a traceback.

As to your `multi/1` … perhaps [setup\_call\_catcher\_cleanup/4](http://www.swi-prolog.org/pldoc/man?predicate=setup_call_catcher_cleanup/4) has what you need?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 12, 2019, 7:06am UTC](https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607/3 "2019-06-12T07:06:58Z")

</div>

> [@gavin.mendel.gleason](#):
>
> multi

See `*->/2`

---

<div class="post-metadata">

**Author:** ![gavin.mendel.gleason](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gavin.mendel.gleason/32/207_2.png) [@gavin.mendel.gleason](https://swi-prolog.discourse.group/u/gavin.mendel.gleason)\
**Post date:** [June 12, 2019, 8:40am UTC](https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607/4 "2019-06-12T08:40:10Z")

</div>

Haha, oops! Thanks for picking that up.

---

<div class="post-metadata">

**Author:** ![gavin.mendel.gleason](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gavin.mendel.gleason/32/207_2.png) [@gavin.mendel.gleason](https://swi-prolog.discourse.group/u/gavin.mendel.gleason)\
**Post date:** [June 12, 2019, 8:43am UTC](https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607/5 "2019-06-12T08:43:30Z")

</div>

It seems to me that the problem with \*-\> is that I’ll end up in the ‘;’ branch regardless of whether there was a solution or not. How can I record that there was at some point a success (or no success)? Seems like I need access to something extralogical - I’ll have a think about how setup\_call\_catcher\_cleanup/4 might be used…

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 12, 2019, 9:28am UTC](https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607/6 "2019-06-12T09:28:35Z")

</div>

> [@gavin.mendel.gleason](#):
>
> I’ll end up in the ‘;’ branch regardless of whether there was a solution or not

No. You only end in the “;” branch if the test has no solutions.

---

<div class="post-metadata">

**Author:** ![gavin.mendel.gleason](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gavin.mendel.gleason/32/207_2.png) [@gavin.mendel.gleason](https://swi-prolog.discourse.group/u/gavin.mendel.gleason)\
**Post date:** [June 12, 2019, 9:30am UTC](https://swi-prolog.discourse.group/t/erroneous-failure-semidet-det-multi/607/7 "2019-06-12T09:30:29Z")

</div>

Indeed! Silly me!
