taway0282
taway0282

Reputation: 197

Prolog - How to over write facts in a semantic network?

I have a semantic network, with the following hierarchy:

Person: has body = true
Man: is a Person, height = 170
Sport Star: is a Man, height = 190

I then want to create instances of these, such as:

Mark: is a Sport Star

However, when I call, for instance height(Mark, X) I get X = 170, and need to press ; to get X = 190. Is there a way to just get 190 straight away?

Upvotes: 1

Views: 315

Answers (2)

Paulo Moura
Paulo Moura

Reputation: 18683

SWI-Prolog, which you indicated you're using, have extensive support for Semantic Web technologies. But if your semantic network consists only of is-a hierarchy relations, you can also easily express them using Logtalk, which you can run with SWI-Prolog and most Prolog systems, making it widely portable:

% Person: has body = true
:- object(person).

    :- public(has/1).
    has(body).

:- end_object.

% Man: is a Person, default height = 170
:- object(man, extends(person)).

    :- public(height/1).
    height(170).

:- end_object.

% Sport Star: is a Man, default height = 190
:- object(sport_star, extends(man)).

    % override inherited height
    height(190).

:- end_object.

% Mark: is a Sport Star
:- object(mark, extends(sport_star)).

:- end_object.

% Spencer: is another Sport Star, but slim
:- object(spencer, extends(sport_star)).

    % override inherited height
    height(165).

:- end_object.

This solution uses a hierarchy of prototypes. Sample calls (deterministic; no spurious choice-points):

?- mark::height(Height).
Height = 190.

?- mark::has(What).
What = body.

?- spencer::height(Height).
Height = 165.

You can create as many prototypes as you need, either defined in a source file or created dynamically at runtime. E.g.

?- create_object(alan, [extends(man)], [], []).
true.

?- alan::height(Height).
Height = 170.

It's also possible to use classes instead of prototypes if you need to distinguish between abstractions and concrete examples of those abstractions.

Upvotes: 4

Marijn
Marijn

Reputation: 1915

The answer by Paulo Moura is a good example of the possibilities of Prolog extensions and libraries. If you are building an actual application then it would be best to use something like that. However, in case you are learning Prolog and you want to know how it works, here an additional pure Prolog answer.

The behavior that you observed is consistent with your knowledge base, which allows two possible interpretations: Mark is a person and therefore his height is 170, or Mark is a sportsman and therefore his height is 195. Both are valid derivations which are supported by the knowledge base, therefore Prolog returns each one in turn.

You can impose extra restrictions on the rules to stop the derivation as soon as the first fact is encountered. The rule is then formulated as "the height of X is either the base fact for things of type X, or, if there is no base fact, follow the isa relation and try again". This requires that the base facts get another name than the rule. The there is no part can be represented with the negation operator \+.

Code:

% isa: general facts
isa(father,man).
isa(man,person).
% isa: specific facts
isa(mark,sportsman).
% height: general facts
height_base(person,170).
height_base(sportsman,195).
% height: rules
height(X,H) :- height_base(X,H).
height(X,H) :- \+height_base(X,_), isa(X,T), height(T,H).

Queries:

?- height(man,X).
X = 170 ;
false.

?- height(mark,X).
X = 195 ;
false.

?- height(sportsman,X).
X = 195 ;
false.

?- height(person,X).
X = 170 ;
false.

Upvotes: 2

Related Questions