# How to parameterize predicate with truth value

**URL:** <https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040>\
**Category:** Help!\
**Created:** [June 8, 2021, 1:57pm UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040 "2021-06-08T13:57:00Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [June 8, 2021, 1:57pm UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/1 "2021-06-08T13:57:00Z")

</div>

Hello,

I’d like to write a kind test predicate that takes as an argument a predicate and whether it is supposed to be true of false.

E.g.  
test(X, Truth)

if call(X) succeeds and Truth = true, then test succeeds, and if call(X) fails and Truth=false, it succeeds as well.

I am thinking about two auxiliary predicates, but is there a more compact way to do this.

Edit:

Right now i did it this way:

```prolog
aux_call(X, true) :-
     !,
    call(X).

aux_call(X, false) :-
    \+ call(X).

test(X, Truth) :-
    aux_call(X, Truth).

```

I guess, this is pretty compact 🙂

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [June 8, 2021, 2:34pm UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/4 "2021-06-08T14:34:28Z")

</div>

Thanks for checking.

My need is currently less broad – I only allow Truth to be ground.

Dan

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [June 9, 2021, 2:39am UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/7 "2021-06-09T02:39:47Z")

</div>

Now I had another case:

Instead of truth values that are expected, to test whether a call should cause an exception to occur.

e.g.

test\_exception(X, true) – X, when called will cause an exception to occur

test\_exception(X, false) – X, when called will not cause an exception to occur

This require playing with catch/3 … after quite a bit of tinkering I came up with the following hack.

With a bit more hacking I could probably also indicate the expected exception name:

```prolog
test_with_exception(X, true) :-
	!, 
	catch(call(X), _Y, p_recover_true).
		
test_with_exception(X, false) :-
	catch(call(X), _Y, p_recover_false(R)),
	!,
	ground(R).
	
p_recover_true :-
	fail.
p_recover_false(false).

```

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [June 9, 2021, 3:39am UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/8 "2021-06-09T03:39:44Z")

</div>

Are you somehow trying to re-implement unit testing? Have you seen this: [https://www.swi-prolog.org/pldoc/doc\_for?object=section('packages/plunit.html')](https://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/plunit.html%27))

Here in particular is an example: [https://www.swi-prolog.org/pldoc/man?section=testerror](https://www.swi-prolog.org/pldoc/man?section=testerror)

In the example above, it shows how to do it with or without the unit test harness.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [June 9, 2021, 3:44am UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/9 "2021-06-09T03:44:50Z")

</div>

Thanks Boris,

Yes, indeed, it did occur to me that i am doing what is also implemented (somehow) in unit testing.

But, its intended for my “application” level, and adapted to the Domain Specific Language I am working on.

Essentially, I want the user of the DSL to be able to create assertion statements that are then called while the DSL is processed.

So, its not in context of unit testing, but more of an assurance device to the DSL user.

Dan

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [June 9, 2021, 3:50am UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/10 "2021-06-09T03:50:52Z")

</div>

Have you looked at how PlUnit implements the tests? Maybe you can reuse some of the code or the logic?

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [June 9, 2021, 6:59am UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/12 "2021-06-09T06:59:53Z")

</div>

Good point – i didn’t think about this.

Usually, X is expected to succeed or to raise an exception – fail is not in scope.

But, i guess, the general case would include fail without exception as well – which would / could count as success.

Btw, since those calls can have side effects i am also wrapping them into a snapshot predicate – to ensure that any side effects are removed.

however, now i noticed that inside i have transaction – so, now i better check if a snapshot … transaction nesting – works to remove changes committed by the “inner” transaction that might succeed.

Dan

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [June 9, 2021, 9:00am UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/14 "2021-06-09T09:00:50Z")

</div>

> [@anon95304481](#):
>
> I think the above works, since the ISO core standard forbids [throw/1](https://www.swi-prolog.org/pldoc/doc_for?object=throw/1) with a variable argument.

Interestingly, my code does generate an anonymous variable within the E structure – making var succeed at all time. I am using domain\_error to throw the exception – need to see why it generates such a unbound thing in E …

Dan

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [June 9, 2021, 10:23am UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/16 "2021-06-09T10:23:07Z")

</div>

> [@anon95304481](#):
>
> `E = error(domain_error(foo, bar), _10460).`

calling domain\_error generates an E such as the one above. But, such a term structure makes var always succeed and ground always fail.

I had such a ground/var variant solution before but then went away from it because of this …

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [June 10, 2021, 3:21am UTC](https://swi-prolog.discourse.group/t/how-to-parameterize-predicate-with-truth-value/4040/19 "2021-06-10T03:21:24Z")

</div>

Yes, exactly …

I thought that ground and var are opposites and when ground didn’t work due to the anonymous variable in the error structure – I assumed that var will also not work.

Thanks for clarifying this …

Dan
