Algorithms in Artificial Intelligence D.M.G. de Champeaux de Laboulaye Aangezien Kunstmatige Intelligentie in Nederland niet erg bekend is en omdat het vak snel verandert, begint dit proefschrift met een tamelijk lange inleiding waarin een overzicht gegeven wordt van het gehele gebied. Uiteraard pretenderen we geenszins dat naar volledigheid gestreefd; daarvoor is het gebied te omvangrijk, terwijl er geen duidelijke hoofdstroom is. Beoefenaars hebben wijduiteenlopende achtergronden: wiskunde, psychologie en linguistiek. De positionering van K.I. ten opzichte van de overige wetenschappen wordt er niet eenvoudiger door. Een van de conclusies uit de inleiding is, dat de samenhang die K.I. gedurende de afgelopen 25 jaar ontegenzeggelijk getoond heeft, niet zozeer veroorzaakt wordt door een onveranderd onderwerp van interesse, maar door een onorthodoxe methodologie: het maken van theorieen die geimplementeerd kunnen worden, zodat niet alleen uitkomsten, maar ín het bijzonder het gedrag van programma’s en zo de daarmee corresponderende processen, bestudeerd kunnen worden. Uiteraard “beperkt” men zich daarbij tot intelligente processen, maar die zijn zeer divers en bij lange na niet geinventariseerd, zodat dit niet een echte beperking genoemd kan worden. Een bekende karakterisering van K.I. ís dat ze nooit een succes kan boeken. Elk behaald resultaat wordt meteen gekleineerd als een onbetekenend speciaal geval van een nog ongebegrepen proces waarin de “echte” intelligentie zich verschuilt. In deze zin hebben we ons met echte K.I. bezig gehouden, want we kunnen niet pretenderen de bestudeerde vraagstukken definitief te hebben verhelderd. De afgelopen jaren hebben we ons in feite met verschillende aandachtsgebieden uit de K.I. bezig gehouden, die men, zoals we in sectie 1.2 hebben beargumenteerd, toch als samenhangend kan beschouwen. Hoofdstuk 2 heeft betrekking op de generalisatie van het z.g.n. A*-algorithme. Het A*-algorithme kan vanuit een gegeven toestand en met gegeven operatoren een pad construeren naar een verlangde toestand. Onder zekere voorwaarden is er de garantie dat, zonder de brute kracht van het nagaan van alle mogelijkheden, toch een kortste pad gevonden zal worden. Het gegeneraliseerde algorithme construeert een oplossing door beurtelings vanaf twee kanten aan een pad te werken. Onder gelijke voorwaarden geldt weer dat een gevonden oplossing een gegarandeerd kortste pad is. Bovendien geldt dat de pad-componenten elkaar ontmoeten in het “midden” van de zoekruimte, daarmee een bekend nadeel van Pohl’s generalisatie vermijdend [66]. Een implementatie van het algorithme wijst uit, dat op een verzameling van 320 problemen er kortere paden dan met het A*-algorithme worden gevonden, terwijl wanneer de beperking wordt opgelegd, dat er per probleem niet meer dan 1000 toestanden worden bezocht, er ook meer oplossingen worden gevonden. In hoofdstuk 3 worden een aantal substitutie functies bestudeerd. Deze zijn vanjbelang omdat ze een centrale rol spelen bij zegene unificatie-algorithmen, die op hun beurt weer de cruciale onderdelen zijn van programma’s voor patroonherkenning en het automatisch bewijzen van stellingen. Omdat de meeste tijd doorgaans wordt doorgebracht in het unificatie-algorithme, is het de moeite waard om efficientie daar tot het uiterste op te voeren. Enkele bekende unificatie-algorithmen, geschreven in LISP, werden aanzienlijk versneld door een niet-copieerende substitutie functie toe te voegen aan het repertoire van LISP en de unificatie-algorithmen enigszins te herschrijven. Het niet-copieren van deze substitutie functie is tot stand gebracht met behulp van zijeffecten van enkele standaard functies. Tot op heden heeft men weinig aandacht geschonken aan het automatische verifieren van programma’s waarin zijeffecten optreden, want het verifieren van gewone programma’s is al lastig genoeg. Het was dan ook een uitdaging om de door ons geintroduceerde substitutie functie op dit punt nader te bestuderen. Een theorie werd ontwikkeld over de semantiek van LISP, waarin voor een ruime klasse van functies met zijeffecten voorzieningen zijn aangebracht. De theorie kon verder worden ontwikkeld dan een soortgelijke die voor PASCAL werd gemaakt. Aangezien programma-verificatie met de hand een zeer bewerkelijke zaak is, ontwikkelden we een z.g.n. symbolische evaluator, die met symbolische invoer alle paden van een programma “doorrekend~. Met behulp van het deductieprogramma, dat in het volgende hoofdstuk gedeeltelijk beschreven wordt, kan vervolgens gecontroleerd worden of de symbolische uitvoer voldoet aan de functiespecificatie, waarmee de verificatie voltooid is. We slaagden erin enkele versies met deze techniek te verifieren, maar moeten anderzijds rapporteren dat er een versie was die zich aan verificatie onttrok, doordat specificatie een hoeveelheid tekst vereist die naar schatting een meer dan honderdvoudige omvang zou krijgen dan de tekst van de code zelf. Het vierde en laatste hoofdstuk beschrijft een tweetal algorithmische deductiemodulen. Het is algemeen bekend dat deductie essentieel onoplosbaar is in die zin dat er geen algorithme kan bestaan dat kan beslissen of een vermoeden al dan niet een theorema is. De zoekruimte is zodanig, dat elk betrouwbaar programma er oneindig lang in kan ronddolen zonder een beslissing te kunnen nemen. Belangrijker is echter dat elk programma dat slechts gebruik maakt van brute kracht, zelfs als te voren bekend is dat een vermoeden in feite te bewijzen is, vastloopt in tijd- en ruimtebeperkingen alvorens het juiste antwoord te vinden. Dat er iets mis is met de brute kracht programma’s blijkt ook uit het feit, dat oplossingen die ze wel vinden voor ons niet inzichtelijk zijn. Dit heeft ons er toe gebracht om “deductieve trucs’, via introspectie verkregen, die een duidelijk afgebakende werking hebben, in algorithmen onder te brengen. We kiezen daarmee voor een deductie “familie” (in principe uitbreidbaar hoewel we ons voorshands verre houden van leerproblemen) bestaand uit algorithmische modulen die een probleem met een hogere prioriteit kunnen aanpakken dan een algemene niet-algorithmische zoekmethode die ook deel uitmaakt van de familie. Een van de modulen tracht een probleem equivalent te herschrijven in een aantal deelproblemen, die in principe eenvoudiger oplosbaar zijn. Een ander moduul kan herkennen dat een probleem een alfabetische variant en/of een speciaal geval is van een ander probleem of een al bekende formule. Eigenschappen van deze modulen worden weer (met de hand) bewezen. Deze modulen werden geintegreerd te samen met een eenvoudige definitie-specialist en een klassieke stellingenbewijzer. Experimenten met o.a. voorbeelden uit de literatuur hebben aangetoond dat dit deductiecomplex inderdaad krachtiger is dan de klassieke zoekcomponent. Als saillant detail zij tenslotte vermeld dat de niet-copieerende substitutie-functie in de stellingbewijzer gebruikt wordt, die op zijn beurt gebruikt is om de correctheid van die substitutie-functie aan te tonen.