Doubly Landlocked Countries

Posted on So 16 Dezember 2018 in misc

Auf der Welt gibt es Staaten, die keine Küste haben. Beispielsweise die Schweiz oder Österreich. Solche Staaten nennt man „Binnenstaaten“ bzw. auf Englisch „landlocked country.“ Weiterhin gibt es Staaten, die nur von Binnenstaaten umgeben sind. Für solche Staaten haben wir im Deutschen keinen schönen Begriff, während sie im Englischen „doubly landlocked countries“ genannt werden.

Man kann auf Wikipedia nachlesen, welche Staaten das sind, aber ich wollte dies schon immer mal selbst herausfinden. Mit Prolog und einer geeigneten Wissensbasis kann man dies herausfinden. Fehlt nur noch die geeignete Wissensbasis. Doch auch dafür eilt die Wikipedia zur Hilfe. Diese Übersichtstabelle muss man nur noch in eine Prologdatei überführen. Dann können wir die grundlegenden Prädikate kennenlernen.

?- country("Germany").
true.

?- continent("Europe").
true.

?- sea("Baltic Sea").
true.

?- is_in("Germany", Continent).
Continent = "Europe".

?- borders("Netherlands", L).
L = ["Belgium", "Germany", "Atlantic Ocean", "North Sea"].

Wie wir sehen gibt es Prädikate für Staaten, Kontinente, Gewässer, Zugehörigkeiten und Grenzen. Das Prädikat borders verknüpft dabei ein Land mit einer Liste von Ländern oder Gewässern, an denen es angrenzt.

Damit können wir die ersten interessanten Anfragen stellen und nützliche Prädikate definieren. Wie viele Länder gehören eigentlich zu Europa, Nordamerika oder Australien?

?- findall(C, (country(C), is_in(C, "Europe")), L), length(L, N).
L = ["Albania", "Andorra", "Austria", "Belarus", "Belgium", "Bosnia and
Herzegovina", "Bulgaria", "Croatia", "Cyprus"|...],
N = 45.

?- findall(C, (country(C), is_in(C, "North America")), L), length(L, N).
L = ["Bahamas", "Canada", "Mexico", "United States"],
N = 4.

?- findall(C, (country(C), is_in(C, "Australia")), L), length(L, N).
L = ["Australia"],
N = 1.

Interessant, dass die Bahamas hier zu Nordamerika zählen, während sie in der deutschsprachigen Wikipedia zu Mittelamerika gehören.

Als erstes Prädikat definieren wir uns is_island, welches gültig ist, wenn der Staat nur von Gewässern umgeben ist.

is_island(Country) :-
    country(Country),
    borders(Country, Nbors),
    forall(member(N, Nbors), sea(N)).

Eine Insel ist ein Land, welches die Nachbarn Nbors hat, sodass für alle N aus Nbors gilt: N ist ein Gewässer. Gibt es Inselstaaten in Europa?

?- is_island(C), is_in(C, "Europe").
C = "Iceland" ;
C = "Malta" ;
false.

Tatsächlich sind das Vereinigte Königreich und Irland laut unserer Definition keine Inselstaaten, weil sie eine gemeinsame Grenze auf dem Land haben.

Kommen wir zum Titelthema: Binnenstaaten. Wir definieren uns das Prädikat is_landlocked, das gilt, wenn ein Land nur von Nachbarn umgeben ist, die keine Gewässer sind.

is_landlocked(Country) :-
    country(Country),
    borders(Country, Nbors),
    forall(member(N, Nbors), not(sea(N))).

Auch hier wieder die Frage: welche und wie viele Länder in Europa, Asien und Südamerika sind Binnenstaaten?

?- findall(C, (is_landlocked(C), is_in(C, "Europe")), L), length(L, N).
L = ["Andorra", "Austria", "Belarus", "Czech Republic", "Hungary", "Liechtenstein", "Luxembourg", "Macedonia", "Moldova"|...],
N = 14.

?- findall(C, (is_landlocked(C), is_in(C, "Asia")), L), length(L, N).
L = ["Afghanistan", "Armenia", "Bhutan", "Kyrgyzstan", "Mongolia", "Nepal", "Tajikistan", "Uzbekistan"],
N = 8.

?- findall(C, (is_landlocked(C), is_in(C, "South America")), L), length(L, N).
L = ["Bolivia", "Paraguay"],
N = 2.

Mit dem Prädikat is_landlocked können wir jetzt is_doubly_landlocked definieren.

is_doubly_landlocked(Country) :-
    country(Country),
    is_landlocked(Country),
    borders(Country, Nbors),
    forall(member(N, Nbors), is_landlocked(N)).

Und los!

?- is_doubly_landlocked(C).
C = "Liechtenstein" ;
false.

Das ist sehr interessant, da Wikipedia neben Liechtenstein auch Usbekistan als doubly landlocked aufführt. Wie kann das sein? Jetzt wird es ein bisschen technisch. Wie wir der Wissensbasis entnehmen können, grenzt Usbekistan an Turkmenistan, welches wiederum an das Kaspische Meer grenzt. Das Kaspische Meer ist aber kein „offenes Meer“ und ist auch nicht mit einem der Weltmeere verbunden. Ebenfalls keine offenen Meere sind der Aralsee, das Tote Meer, der Saltonsee und der See Genezareth. Wenn wir die Wissensbasis anpassen und das Prädikat high_sea definieren, welches für alle bisherigen Gewässer außer dem Aralsee und dem Kaspischen Meer gilt, dann können wir die richtigen Prädikate für landlocked und doubly landlocked definieren.

is_technically_landlocked(Country) :-
    country(Country),
    borders(Country, Nbors),
    forall(member(N, Nbors), not(high_sea(N))).

is_technically_doubly_landlocked(Country) :-
    country(Country),
    borders(Country, Nbors),
    forall(member(N, Nbors), is_technically_landlocked(N)).

Und damit erhalten wir:

?- is_technically_doubly_landlocked(C).
C = "Liechtenstein" ;
C = "Uzbekistan" ;
false.

Zuletzt gibt die Englischsprachige Wikipedia weitere Denkanstöße:

  • Welche Staaten sind Enklaven (also komplett von einem anderen Land umschlossen)?
  • Welche Staaten sind Semi-Enklaven (also komplett von zwei Staaten umschlossen)?

Auch dafür definieren wir uns Prädikate:

is_enclaved(Country) :- country(Country), borders(Country, [N]), country(N).
is_semi_enclaved(Country) :-
    is_landlocked(Country),
    borders(Country, [N1, N2]),
    borders(N1, Nbors1),
    borders(N2, Nbors2),
    member(N1, Nbors2),
    member(N2, Nbors1).

Und siehe da, hierbei stimmen unsere Ergebnisse mit denen der Wikipedia überein:

?- is_enclaved(C).
C = "Lesotho" ;
C = "San Marino" ;
C = "Vatican City" ;
false.

?- is_semi_enclaved(C).
C = "Andorra" ;
C = "Bhutan" ;
C = "Liechtenstein" ;
C = "Moldova" ;
C = "Mongolia" ;
C = "Nepal" ;
C = "Swaziland" ;
false.