:- module(datenbank,[astronom/1,stern/1,sonne/1,
                     planet/2,mond/2,durchmesser/2,
                     objekt/1,mond/1,planet/1,
                     umkreisen/2,entdecken/2]).

% Datensaetze: db(S,A,D,E,Z) für
% db(Stern,Art,Durchmesser,Entdecker,Zentralstern)

db(  sonne,  sonne, 1392000,        _,     _).
db(   erde, planet,   12756,        _, sonne).
db(jupiter, planet,  142800,        _, sonne). 
db(   mars, planet,    6887,        _, sonne).
db( merkur, planet,    4878,        _, sonne).
db( neptun, planet,   49500,        _, sonne).
db(  pluto, planet,    3000, tombaugh, sonne).

db( saturn, planet,  120600,        _,   sonne).
db( uranus, planet,   51800, herschel,   sonne).
db(  venus, planet,   12100,        _,   sonne).

db( adrastea, mond,      24,        _, jupiter).
db( amalthea, mond,     135,        _, jupiter).
db(   ananke, mond,      30,nicholson, jupiter).
db(    ariel, mond,    1158,  lassell,  uranus).
db(    carme, mond,      40,  melotte, jupiter).
db(   charon, mond,    1000,        _,   pluto).
db(   deimos, mond,       8,     hall,    mars).
db(    diana, mond,    1100,  cassini,  saturn).
db(    dione, mond,    1120, herschel,  saturn).
db(    elara, mond,      76,nicholson, jupiter).
db(enkeladus, mond,     500, herschel,  saturn).
db(   europa, mond,    3138,  galilei, jupiter).
db(  ganymed, mond,    5262,  galilei, jupiter).
db(  himalia, mond,     186,  perrine, jupiter).
db( hyperion, mond,     205,     bond,  saturn).
db(  iapetus, mond,    1460,  cassini,  saturn).
db(       io, mond,    3630,  galilei, jupiter).
db( kallisto, mond,    4800,  galilei, jupiter).
db(    mimas, mond,     392, herschel,  saturn).
db(     mond, mond,    3476,        _,    erde).

db(    titan, mond,    5150, huyghens,  saturn).
db(   triton, mond,    2700,  lassell,  neptun).

% Zugriffspraedikate:  

stern(S) :-    db(S,_,_,_,_).
sonne(S) :-    db(S,sonne,_,_,_).
astronom(X) :-
    setof(E,S^A^D^Z^(db(S,A,D,E,Z), atom(E)),Es),
    member(X,Es).  % vermeidet Mehrfachnennungen

mond(S,Z) :-   db(S,mond,  _,_,Z).
planet(S,Z) :- db(S,planet,_,_,Z).
umkreisen(S,Z) :- db(S,_,_,_,U), atom(U), Z = U.
entdecken(E,S) :- db(S,_,_,A,_), atom(A), E = A.
durchmesser(D,S) :- db(S,_T,D,_E,_Z).

mond(S) :- mond(S,_).
planet(S) :- planet(S,_).

objekt(X) :-  atomic(X), !,
    (stern(X) ; astronom(X) ; durchmesser(X,_)).
objekt(X:T) :- type(X/0,T).
    
% type(+Praedikat/Stelligkeit,-Typ)
%    m=Mensch, s=Gestirn, n=Zahl, e=Entität, t=Wahrheitswert
type(N/0,m) :- astronom(N).
type(N/0,s) :- stern(N).
type(N/0,n) :- durchmesser(N,_).
type(objekt/1,(e -> t)).   type(eq/2,(T*T -> t)).
type(astronom/1,(m -> t)). 
type(sonne/1,(s -> t)).    type(stern/1,(s -> t)).
type(planet/1,(s -> t)).   type(mond/1,(s -> t)).
type(planet/2,(s*s -> t)). type(mond/2,(s*s -> t)).   
type(entdecken/2,(m*s -> t)). type('=<'/2,(n*n -> t)).   
type(umkreisen/2,(s*s -> t)). type('<'/2,(n*n -> t)).    
type(durchmesser/2,(n*s -> t)).

subtype(X,Y) :-
    (var(X) ; var(Y)), !, X = Y.
subtype(s,e).
subtype(m,e).
subtype(n,e).
subtype(X*Y,U*V) :-
    subtype(X,U), subtype(Y,V).
subtype((A -> B),(C -> D)) :-
   subtype(C,A), subtype(B,D).
subtype(X,X).

