:- 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).

% Erweiterung für Vergleiche: Dimensionen, Typen usw.
dim(gross,+,groesse).
dim(klein,-,groesse).
skala(groesse,dimSkala).

quant(groesse,Obj,Grad) :- 
    durchmesser(Grad,Obj). % fuer Sterne

% Eher ein Qualitaetsadjektiv:
% quant(groesse,Obj,Grad) :- % fuer Astronomen
%     antworten(qu(X, mond(X) & entdecken(Obj,X)),Xs),
%     length(Xs,M),
%     antworten(qu(X,planet(X) & entdecken(Obj,X)),Xs),
%     length(Xs,P),
%     Grad is (4 * ZP + 2 * ZM). % gewichtete Leistung

objekt(X:e) :- type(X/0,e).
objekt(X:g) :- type(X/0,g). 
objekt(X:d) :- type(X/0,d). 

type(X/0,e) :- stern(X) ; astronom(X).
type(X/0,g) :- quant(_,_,X).
type((+)/0,t). % Type p ?
type((-)/0,t). % Type p ?
type(groesse/0,d).
type(dimSkala/0,s).

type(eq/2,(e*e -> t)).
type('&'/2,(t*t -> t)).
type('\/'/2,(t*t -> t)).
type('=>'/2,(t*t -> t)).
type('<=>'/2,(t*t -> t)).

type(dim/3,g*p*d -> t).
type(quant/3,d*e*g -> t).
type(lt/3,d*e*e -> t).
type(eq/3,d*e*e -> t).
type(lt/4,d*e*e*n -> t).

