%Nr: DS-1995-19 %Author: Erik Aarts %Title: Investigations in Logic, Language and Computation In dit proefschrift wordt de tijdscomplexiteit van drie problemen bekeken. De tijdscomplexiteit van een probleem is de relatie tussen de benodigde rekentijd om een probleem op een computer op te lossen en de omvang van het probleem. In deze relatie laten we constante factoren weg. Stel dat we een object en een ongesorteerde lijst hebben, en dat we willen weten of het object voorkomt in de lijst. De omvang van het probleem is de lengte van de lijst. Die noemen we n. Als we de lijst langslopen en elk object in de lijst vergelijken met het object dat we zoeken is de benodigde rekentijd in het slechtste geval O(n) (orde n). Als de relatie tussen rekentijd en omvang van een probleem een polynomiale functie is (O(n^k) met k vast), zeggen we dat het probleem in P (Polynomiale tijd) zit. Vaak is een probleem moeilijk op te lossen, maar is het controleren van de oplossing eenvoudig. Stel we hebben een groot getal dat het product is van twee grote priemgetallen en dat het probleem is: "vind de twee priem- factoren". Een zeer eenvoudig algoritme is het volgende: probeer alle kleinere getallen als deler van het getal dat ontbonden moet worden. Als het getal n cijfers heeft, moeten we O(10^n) getallen proberen als priemfactor. Dit is duidelijk niet polynomiale tijd, maar exponentiele. Er zijn overigens veel betere algoritmes bekend, maar die werken ook in exponentiele tijd. Het controleren van een oplossing kan wel in polynomiale tijd: als we twee getallen hebben hoeven we alleen maar te vermenigvuldigen om te zien of het product inderdaad het getal is dat ontbonden moest worden. De klasse van problemen met de eigenschap dat oplossingen gemakkelijk gecontroleerd kunnen worden heet NP (nondeterministische polynomiale tijd). Problemen in NP waarvan vermoed wordt dat ze niet in P zitten heten NP-compleet. Ontbinden in priemfactoren is NP-compleet. Het eerste deel van dit proefschrift beschrijft de tijdscomplexiteit van problemen in twee gebieden: de categoriale grammatica's en de acyclische context-gevoelige grammatica's. Categoriale grammatica's bestaan uit een lexicon waarin types worden toegekend aan lexicale elementen en uit een sequenten calculus waarin geredeneerd kan worden over afleidbaarheid van types. Een type A is afleidbaar uit een rijtje typen \Gamma als de sequent \Gamma \implies A afleidbaar is in de sequenten calculus. We kunnen een categoriale taal definieren als die verzameling strings waarvoor geldt dat ze via het lexicon op een rijtje types afgebeeld kunnen worden en dat uit dit rijtje het type s (of een ander "starttype") afleidbaar is in de sequenten calculus. Het probleem dat we bekijken is dat we van een bepaalde string willen weten of die in de categoriale taal zit. Het is niet bekend of dit probleem, bij gebruik van de standaard Lambek calculus, in P zit of juist NP-compleet is. Dit proefschrift laat zien dat voor bepaalde fragmenten het probleem in P zit. Die fragmenten zijn de grammatica's waarbij de niet-associatieve Lambek calculus en de tweede orde Lambek calculus worden gebruikt (met tweede orde wordt bedoeld dat de nestingsdiepte van types hooguit twee is). Acyclische context-gevoelige grammatica's zijn herschrijf grammatica's die boomstructuren met kruisende takken kunnen genereren. Dit gebeurt door indices toe te kennen aan de context elementen in de herschrijfregel. We hebben gekeken naar het probleem of een bepaalde string in de gegenereerde taal zit. Als we gewone context-gevoelige grammatica's gebruiken is dit een heel moeilijk probleem, moeilijker dan de NP-complete problemen. Daarom eisen we dat de grammatica acyclisch is. We laten zien dat het probleem in P zit als we alleen de invoerzinnen varieren en de grammatica vast houden. Als de grammatica ook mag varieren (en dus een rol speelt in "de omvang van het probleem"), dan wordt het probleem NP-compleet. Het tweede deel van dit proefschrift gaat over Prolog programma's. Prolog is een zeer eenvoudige, krachtige programmeertaal. Het grootste verschil met andere programmeertalen is dat het mogelijk is om niet-deterministische programma's te coderen. Omdat computers deterministische machines zijn moeten Prolog programma's op een bepaalde manier omgezet worden naar deterministische programma's. De standaard manier om dit te doen is eerst-in-de-diepte (depth-first) met terugkrabbelen (back-tracking). Als er een keuze gemaakt moet worden, wordt de eerste optie genomen. Als blijkt dat deze keuze op geen enkele manier tot resultaat leidt wordt de volgende optie geprobeerd, enzovoort. In dit proefschrift wordt naar een alternatieve zoekstrategie (OLDT resolutie) gekeken. In deze strategie wordt bijgehouden welke alternatieven geprobeerd zijn en met welk resultaat. Deze strategie voorkomt dat een bepaalde deelberekening twee keer wordt uitgevoerd. In de standaard methode kan de zoekruimte als een boom gerepresenteerd worden. Twee knopen in de boom kunnen best hetzelfde deelprobleem representeren. Bij OLDT resolutie representeren alle knopen in de zoekruimte per definitie verschillende deelproblemen; de zoekruimte is dan ook geen boom meer maar een graaf. Het idee dat in dit proefschrift uitgewerkt is, is dat de omvang van de zoekruimte een maat is voor de rekentijd die door een Prolog programma wordt gebruikt, daar elke tak in de zoekruimte maar 1 keer bewandeld wordt. In het tweede deel van het proefschrift wordt een methode gegeven om van een Prolog programma de benodigde rekentijd te schatten onder de assumptie dat OLDT-resolutie wordt gebruikt bij de executie van het programma. Tenslotte worden de delen 1 en 2 gecombineerd. We geven Prolog programma's die uitrekenen of een string in een categoriale taal zit (voor de beide fragmenten). Vervolgens laten we zien dat de rekentijd, die die Prolog programma's nodig hebben, polynomiaal is in de lengte van de zin en in de lengte van het lexicon.