How to make Prolog queries case-insensitive?

186 views
Skip to first unread message

Rex

unread,
Nov 6, 2014, 5:04:09 PM11/6/14
to swi-p...@googlegroups.com
Let's say we have following facts:
:-   'Abc'(NULL).
:-   'Abc'(xyz).

I want to make all following queries to be true based on the facts above:
?-   abc(X).
?-   abC(X).
?-   aBc(X).
?-   aBC(X).
?-   'Abc'(X).
?-   'AbC'(X).
?-   'ABc'(X).
?-   'ABC'(X).

and
?-   abc(''Xyz').

Is there any option in SWI-Prolog that we can set-up to make Prolog queries case-insensitive?


Kilian Evang

unread,
Nov 6, 2014, 5:34:43 PM11/6/14
to swi-p...@googlegroups.com
On 06/11/14 23:04, Rex wrote:
> Let's say we have following facts:
> :- 'Abc'(NULL).
> :- 'Abc'(xyz).

These don't look like facts but like directives. Do you mean

'Abc'(NULL).
'Abc'(xyz).

?

> I want to make all following queries to be true based on the facts above:
> ?- abc(X).
> ?- abC(X).
> ?- aBc(X).
> ?- aBC(X).
> ?- 'Abc'(X).
> ?- 'AbC'(X).
> ?- 'ABc'(X).
> ?- 'ABC'(X).
> and
> ?- abc(''Xyz').
>
> Is there any option in SWI-Prolog that we can set-up to make Prolog
> queries case-insensitive?

*In theory*, if your facts are read from a source file (and not asserted
dynamically), you could use term expansion [1] to generate all case
variants.

But this would be a very weird thing to do and the number of generated
facts would explode if your functor name gets longer than very few
characters. So what you probably want to do is change the form of your
facts to something like

f('Abc', NULL).
f('Abc', xyz).

and query them via an auxiliary predicate that does the case
normalization for the arguments. If you're not sure, say a bit more
about what you actually want your program to do so we can advise you on
what approach might be suitable.

[1] http://www.swi-prolog.org/pldoc/doc_for?object=term_expansion/2

Jan Burse

unread,
Nov 7, 2014, 10:27:53 AM11/7/14
to swi-p...@googlegroups.com
Easy, lets assume for simplicity that the facts are
define with lower case:

     abc(null).
     abc(xyz).

The define a new meta predicate:

calllc(X) :-
    X =.. [F|L],
    downcase_atom(F, G),
    Y =.. [G|L],
    call(Y).

You should then be able to call:

     ?- calllc('AbC'(X)).
     ?- calllc('aBc'(X)).
     Etc..

Bye
Reply all
Reply to author
Forward
0 new messages