Prologue. In the query, how to put a condition on a variable that I do not want in the results?

Imagine that I have the following knowledge base, which gives each person their own name and age.

person(mary, 39).
person(john, 24).
person(sandy, 17).

Now I want to get all people over 20 years old. In addition, I just want to collect their names, not their age. Here I want to get maryand john.

How to do this usually in Prolog and more specifically in SWI-Prolog?

If we use a variable that is not anonymous, for example:

?- person(X, Y), Y > 20.

Prolog will give me values ​​for Xand Y, and I don't want to Y.

I cannot use an anonymous variable _because Prolog cannot bind its two instances. The following is the error:

?- person(X, _), _ > 20.

So how to do this?

+4
3

ofintrest(X):- person(X,Y),Y>20.

ofintrest(X).

,

person(X,_) ,\+(\+ (person(X,Y), Y>20))
+4

@danielp.

:

  • ( )

  • _A

. Prolog.

SWI: ( Prolog).  current_prolog_flag/2.  set_prolog_flag/2.

< > stefan @Lenovo ~ $swipl SWI-Prolog (, 64 , 7.3.15) ... ? - current_prolog_flag (toplevel_print_anon, ), % = true. ? - _A = 1. _A = 1. ? - _A = 1, X = _A. _A = X, X = 1. ? - set_prolog_flag (toplevel_print_anon, false). % toggle flag . ? - current_prolog_flag (toplevel_print_anon, ). = false. ? - _A = 1.% ! . ? - _A = 1, X = _A. X = 1. ? - set_prolog_flag (toplevel_print_anon, true). % . ? - current_prolog_flag (toplevel_print_anon, ). = true. ? - _A = 1. _A = 1. ? - _A = 1, X = _A. _A = X, X = 1.
+5

You can define a predicate already sent in response to CAFEBABE . In addition, you can also specify a name starting with a _variable whose values ​​should not be displayed in the response (as you already noted, occurrences _are always different variables):

person(X,_Age), _Age > 20.

Update . This applies to the implementation of Prolog. It works for SICStus, but not for SWI by default (see repeat answer ).

+2
source

Source: https://habr.com/ru/post/1625068/


All Articles