Programming in Tabled Prolog (Very) DRAFT 1
Total Page:16
File Type:pdf, Size:1020Kb
Programming in Tabled Prolog (very) DRAFT 1 David S. Warren Department of Computer Science SUNY @ Stony Brook Stony Brook, NY 11794-4400, U.S.A. February 28, 2020 1This is a very early draft made available privately for those who might find it of interest. I reserve all rights to this work. -dsw Contents 1 Background and Motivation 1 2 Introduction to Prolog 6 2.1 Prolog as a Procedural Programming Language . ........... 6 2.1.1 Assign-onceVariables . ..... 7 2.1.2 Nondeterminism ................................ 11 2.1.3 ExecutingProgramsinXSB. 13 2.1.4 The Scheduling of Machine Execution in Prolog . .......... 18 2.2 GrammarsinProlog ................................ 21 2.3 PrologasaDatabaseQueryLangauge . ........ 26 2.4 DeductiveDatabases .............................. ...... 27 2.5 Summary ......................................... 30 2.6 Exercises ....................................... 30 2.7 ExerciseDiscussion.............................. ....... 32 3 Introduction to First-Order Logic 34 3.1 PropositionalLogic.............................. ....... 36 3.1.1 Syntax........................................ 36 3.1.2 Semantics..................................... 36 i CONTENTS ii 3.1.3 Deduction..................................... 38 3.1.4 HornClauses ................................... 41 3.2 FirstOrderLogic(FOL). .. .. .. .. .. .. .. .. ...... 44 3.2.1 Syntax........................................ 44 3.2.2 Semantics..................................... 46 3.2.3 Deduction..................................... 49 3.3 Exercises ....................................... 58 4 Tabling and Datalog Programming 63 4.1 MoreonTransitiveClosure . ....... 68 4.2 OtherDatalogExamples. ...... 72 4.3 SomeSimpleGraphProblems. ...... 73 4.3.1 Stongly Connected Components in a DAG . ...... 73 4.3.2 Connected Components in an Undirected Graph . ........ 74 4.4 GenomeExamples .................................. 75 4.5 SubsumptiveTabling.. .. .. .. .. .. .. .. .. ...... 75 4.6 InferringWhentoTable . .. .. .. .. .. .. .. .. ...... 75 4.7 Datalog Optimization in XSB . ....... 80 4.8 Exercises ....................................... 80 5 Grammars 83 5.1 AnExpressionGrammar. .. .. .. .. .. .. .. .. ..... 83 5.2 RepresentingtheInputStringasFacts . ........... 85 5.3 Mixing Tabled and Prolog Evaluation . ......... 87 5.4 SoWhatKindofParserisit?. ...... 88 5.5 BuildingParseTrees .............................. ...... 89 CONTENTS iii 5.6 ComputingFirstSetsofGrammars. ........ 92 5.7 LinearParsingofLL(k)andLR(k)Grammars . ......... 94 5.8 Parsing of Context Sensitive Grammars . .......... 98 5.9 SubstringMatching............................... 102 5.10Exercises ...................................... 105 6 Automata Theory in XSB 108 6.1 FiniteStateMachines ............................. 108 6.1.1 IntersectionofFSM’s . .. .. .. .. .. .. .. 111 6.1.2 Epsilon-freeFSM’s . .. .. .. .. .. .. .. .. 112 6.1.3 DeterministicFSM’s . 114 6.1.4 ComplementsofFSM’s ............................ 116 6.1.5 Minimization of FSM’s . 119 6.1.6 RegularExpressions . 123 6.2 GrammarsRevisited ............................... 126 6.3 Push-DownAutomata ............................... 128 6.4 Exercises ....................................... 128 7 Dynamic Programming in XSB 130 7.1 TheKnap-SackProblem. .. .. .. .. .. .. .. .. 130 7.2 SequenceComparisons . .. .. .. .. .. .. .. .. 132 7.3 ?? .............................................. 133 7.4 Exercises ....................................... 133 8 HiLog Programming 134 8.1 GenericPrograms ................................. 134 CONTENTS iv 8.2 Object Centered Programming in XSB with HiLog . ..........138 9 Debugging Tabled Programs 139 10 Aggregation 141 10.1 Tabled Agggregation and Lattice Operations: Min, Max . ...............142 10.2 Tabled Agggregation and the Fold Operation: sum . .............143 10.3LongPathExample ................................ 148 10.4 RecursiveAggregation . ........150 10.4.1 ShortestPath................................. 150 10.4.2 Reasoning with Uncertainty: Annotated Logic . ...........151 10.4.3 LongestPath .................................. 152 10.4.4 Markov Decision Processes . 152 10.5 SchedulingIssues ............................... .......154 10.6 Stratified Aggregation . ........154 11 Incremental Table Maintenance 155 12 Negation in XSB 156 12.1 CompletionSemantics . .......160 12.2 Negation through Fixed Points . .........163 12.3 GeneralNegation................................ 169 12.3.1 Clark’s Completion Semantics . ........170 12.3.2 StableModelSemantics . 172 12.3.3 Well-Founded Semantics . 174 12.4 OtherStufftothinkabout? . .......179 12.5 ApproximateReasoning . .......179 CONTENTS v 12.6 Representation of Partial Knowledge with Well-FoundedModels . .. .. ..180 13 Meta-Programming 185 13.1 Meta-InterpretersinXSB . ........185 13.1.1 A Metainterpreter for Disjunctive Logic Programs . .............185 13.1.2 A Metainterpreter for Explicit Negation . ...........185 13.2 AbstractInterpretation . .........185 13.2.1 AI of a Simple Nested Procedural Language . .........186 14 XSB Modules 191 15 Handling Large Fact Files 192 15.1Indexing....................................... 192 15.2 CompilingFactFiles . .......195 15.3 Dynamically Loaded Fact Files . .........196 15.4 IndexingStaticProgramClauses . ..........197 16 Table Builtins 199 17 XSB System Facilities 200 Chapter 1 Background and Motivation There is a flaw in the very foundations of Logic Programming: Prolog is nondeclarative. Of course, everyone knows that real Prolog as it is used is nondeclarative. Prolog programs abound with cuts, var tests, asserts, and all kinds of ugly warts. Everyone agrees that Prolog should be more declarative and much research time has been spent, and spent productively, trying to remedy these problems by providing more declarative alternatives. But I believe that there is a more serious flaw closer to the heart of Prolog, right at its very center, and this flaw has caused a number of problems in logic programming. I’m convinced that we must address this flaw, before we can proceed together productively with logic programming. Of course, whether this is a “flaw” is in the eye of the beholder; we all have arguments over whether a particular behavior is a bug or a feature. As is clear from my presentation, I think I’ve found a bug; some of you will think it’s a feature. Wherever we stand on this issue, however, I believe we must be clear about its implications. Only then will we be able to communicate effectively about where LP is and where it should go. Let me also mention that I am by no means pointing out something new, unknown to the community; rather I’m trying to raise our consciousness about an inconsistency and its implications. The problem is the very semantics of logic programming. The foundational results of our field show that for pure horn clauses, the following are equivalent: logical implication, SLD resolution, and the least fixpoint of the Tp operator. And logic programming basically “works” because SLD corresponds to computation (i.e. Prolog) and to logical implication (truth in models). But there is a fly in the ointment, the dirty secret that we Prolog aficionados try to keep in the closet but Prolog programmers are all too aware of. Let’s look more carefully at the full SLD tree, the foundation for us Prolog hackers. There are three kinds of paths in an SLD tree: 1) those ending in success, 2) those ending in failure, and 3) those not ending. The foundational results tell us that those ending in success correspond exactly to those instances of the query that logically follow from the program. This is fine and dandy and certainly something we want and need. But as programmers, that’s not enough. We programmers also want, need actually, to distinguish between paths that end in failure and paths that don’t end at all. When we run a program, and it responds ‘no’, we may accept that response as a good answer to our query. But if it goes into an infinite 1 CHAPTER 1. BACKGROUND AND MOTIVATION 2 loop never coming back with an answer at all, we decide we have a bug in our program and set out to fix it. So the problem with SLD is not that it doesn’t do the right things for success, but that it doesn’t do the right thing with the other two possible outcomes. Note that this has nothing to do with how we search the SLD tree, e.g. unfairly with depth first search or fairly with breadth-first search; it’s a property of the tree itself. And it has nothing to do with the fact that our theory deals best with ground programs and Prolog programs deal with variables. The problem concerns which paths in the SLD tree are finite and which are infinite. In Prolog, as compared with other languages, it seems easier to write partially correct pro- grams, programs that, if they halt, they give the right answers. This comes from the power of declarative programming. But it seems much harder to write and reason about totally correct programs, programs that halt in all (the right) cases. So it may be the case that what we gain from declarativeness in our ability to reason about the partial correctness of Prolog programs, we lose in the difficulty of reasoning about total correctness. Theoreticians may accept partial correctness as good enough; but we users have to know precisely how partial. And sadly, the problems show up for very simple programs. The issue is clearly seen in transitive closure. Consider the definition: tca(X,Y) :- a(X,Y). tca(X,Y) :- a(X,Z), tca(Z,Y). Prolog programmers know that this definition is fine when the predicate