Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with unknown procedure error in SWI-Prolog

Tags:

prolog

I'm attempting to create a simple knowledge base using Swi-Prolog but I'm encountering an 'Unknown Procedure' error when I run the query animal(X).. To my knowledge, it should print 'Alligator' based on the facts I wrote below. What am I doing wrong?

species(reptile):-
    scales(present),
    body_temperature(cold_blooded),
    reproduction(lays_eggs).

animal(alligator):-
    species(reptile),
    color(dark_green),
    habitat(water).

species(reptile).
color(dark_green).
habitat(water).
like image 244
kimetsu no yaiba Avatar asked Oct 12 '25 04:10

kimetsu no yaiba


2 Answers

Your program contains no variables, only constants, here in the form of atoms (all-lowercase letter strings)

The error:

ERROR: Unknown procedure: scales/1
ERROR: In:
ERROR:   [12] scales(present)
ERROR:   [11] species(reptile) at user://1:8
ERROR:   [10] animal(alligator) at user://1:13
ERROR:    [9] toplevel_call(user:user: ...) 

The interpreter is looking for the predicate scales/1 to call with argument present. There is no such predicate (no fact or rule named that way can be found).

It is also not clear what your program is supposed to do.

You may want to express this:

"Typing" facts about certain atoms (these are often less useful than one would think.

animal(alligator).     % alligator is an animal
species(reptile).      % reptile is a species    
color(dark_green).     % dark_green is a color
habitat(water).        % water is a habitat

Attributes of the thing designated by alligator:

species(alligator,reptile).   % species of alligator is reptile
color(alligator,dark_green)   % color of alligator is dark_green
habitat(alligator,water).     % habitat of alligator is water

Attributes of the thing designated by species:

surface(reptile,scales).
body_temperature(reptile,cold_blooded),
reproduction(reptile,lays_eggs).

Prolog's ability to model objects properly is a bit anaemic. The lack of the basically useful data structure "map" doesn't help. (Is Prolog the "assembler of ontologies"? Yes it is!)

like image 96
David Tonhofer Avatar answered Oct 14 '25 22:10

David Tonhofer


Given that you problem requires representing taxonomic knowledge, Let's use a Logtalk solution that can naturally express it, providing a one-to-one relation between the knowledge and its code representation. This solution is portable and can thus run in most Prolog systems:

:- object(species).

    :- public([
        scales/1, body_temperature/1, reproduction/1,
        color/1, habitat/1
    ]).

:- end_object.


:- object(reptile, extends(species)).

    scales(present).
    body_temperature(cold_blooded).
    reproduction(lays_eggs).

:- end_object.


:- object(alligator, extends(reptile)).

    species(reptile).
    color(dark_green).
    habitat(water).

:- end_object.

Save this code in a, say, kb.lgt file, start Logtalk with your preferred Prolog system and try some queries. For example:

$ swilgt
...
{kb}.
...
?- alligator::habitat(Habitat).
Habitat = water.

?- alligator::reproduction(Reproduction).
Reproduction = lays_eggs.

But you also want to enumerate e.g. animals. I.e. reasoning about the hierarchy. There's a library for that. First, we need to import the necessary predicates into the root object:

:- object(species, imports(proto_hierarchy)).

We can then try:

?- {hierarchies(loader)}.
...
?- reptile::descendant(Reptile).
Reptile = alligator ;
false.

This example should be, hopefully, clear enough so that you can extend it to be more realistic in a way that would avoid your old Biology teacher screaming and pulling hair. It's also easy to evolve this solution into an expert system that could be used to classify a being given its description. For an example, see:

https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/birds

like image 25
Paulo Moura Avatar answered Oct 14 '25 22:10

Paulo Moura