├── _config.yml ├── _data ├── authors.yml └── navigation.yml ├── _includes └── footer.html ├── course-overview.md ├── decision-procedure.png ├── index.md ├── lecture-notes ├── 2019-09-30-the-science-of-brute-force.md ├── 2019-09-30-the-science-of-brute-force.pdf ├── 2019-10-02-introduction-to-decision-procedures-1.md ├── 2019-10-02-introduction-to-decision-procedures-1.pdf ├── 2019-10-04-introduction-to-decision-procedures-2.md ├── 2019-10-04-introduction-to-decision-procedures-2.pdf ├── 2019-10-07-introduction-to-sat-solving-1.md ├── 2019-10-07-introduction-to-sat-solving-1.pdf ├── 2019-10-09-introduction-to-sat-solving-2.md ├── 2019-10-09-introduction-to-sat-solving-2.pdf ├── 2019-10-11-introduction-to-smt-solving.md ├── 2019-10-11-introduction-to-smt-solving.pdf ├── 2019-10-14-theories-equality-and-uninterpreted-functions.md ├── 2019-10-14-theories-equality-and-uninterpreted-functions.pdf ├── 2019-10-16-theories-linear-arithmetic.md ├── 2019-10-16-theories-linear-arithmetic.pdf └── build.sh ├── presentations ├── Putting Consistency Back into Eventual Consistency 11_20.pdf ├── README.md ├── kaplan-presentation-final.pdf ├── klee-presentation-final.pdf ├── liquid_types.pdf └── refinement_types_for_haskell.pdf └── readings.md /_config.yml: -------------------------------------------------------------------------------- 1 | title: "CSE290Q, Fall 2019" 2 | description: "SMT Solving and Solver-Aided Systems" 3 | 4 | remote_theme: "mmistakes/minimal-mistakes" 5 | minimal_mistakes_skin: "default" # "air", "aqua", "contrast", "default", "dark", "dirt", "neon", "mint", "plum", "sunrise" 6 | 7 | repository: "lkuper/CSE290Q-2019-09" 8 | 9 | url: "https://decomposition.al" 10 | 11 | baseurl: "/CSE290Q-2019-09" 12 | 13 | plugins: 14 | - jekyll-include-cache 15 | -------------------------------------------------------------------------------- /_data/authors.yml: -------------------------------------------------------------------------------- 1 | Lindsey Kuper: 2 | name : "Lindsey Kuper" 3 | avatar : "https://users.soe.ucsc.edu/~lkuper/lindsey_kuper.jpg" 4 | links: 5 | - label: "Email" 6 | icon: "fas fa-fw fa-envelope-square" 7 | url: "mailto:lkuper@ucsc.edu" 8 | - label: "Website" 9 | icon: "fas fa-fw fa-link" 10 | url: "https://decomposition.al" 11 | - label: "Twitter" 12 | icon: "fab fa-fw fa-twitter-square" 13 | url: "https://twitter.com/lindsey" 14 | -------------------------------------------------------------------------------- /_data/navigation.yml: -------------------------------------------------------------------------------- 1 | main: 2 | - title: "Home" 3 | url: /index.html 4 | - title: "Course Overview" 5 | url: /course-overview.html 6 | - title: "Readings" 7 | url: /readings.html 8 | -------------------------------------------------------------------------------- /_includes/footer.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /course-overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Course overview" 3 | layout: single 4 | classes: wide 5 | --- 6 | 7 | ## What's this? 8 | 9 | This is a first-day-of-class overview of the fall 2019 edition of CSE290Q ("SMT Solving and Solver-Aided Systems"), a graduate seminar course in the Computer Science and Engineering Department at the UC Santa Cruz Baskin School of Engineering. 10 | 11 | ## Instructor 12 | 13 | Hi, I'm [Lindsey Kuper](https://users.soe.ucsc.edu/~lkuper/)! (Call me "Lindsey".) 14 | 15 | - Email: 16 | - Office location: Engineering 2, Room 349B 17 | - Office hours: Fridays, 1:30-2:30pm, or by appointment ([email me](mailto:lkuper@ucsc.edu)) 18 | - Research areas: Programming languages, distributed systems, parallelism, concurrency, software verification 19 | 20 | ## A few essential details about the course 21 | 22 | - 5-unit graduate seminar course (i.e., a course where we read, present, and discuss research papers) 23 | - Satisfies the [breadth requirement](https://www.soe.ucsc.edu/departments/computer-science-and-engineering/graduate/breadth-requirements) in the "Software Engineering and Programming Languages" category for the UCSC CS MS and Ph.D. programs 24 | - Class meets Mondays, Wednesdays, and Fridays, 2:40-3:45pm, Engineering 2, Room 192 25 | - No final exam, although you should save the time slot (8-11am on Thursday, December 12) for a social event 26 | - Course web page: 27 | - Course GitHub repo: 28 | - Canvas: 29 | - This document: 30 | 31 | ## What's this course about? 32 | 33 | [SAT](https://dl.acm.org/citation.cfm?id=1536637) and [SMT](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories) solvers are now widely used across many areas of computer science, especially for automated software and hardware verification, but they are often "black boxes" to their users. This course is for those who want to look under the hood to learn how solvers work, and to explore a variety of systems that make use of them. 34 | 35 | About three weeks of the course will focus on SAT and SMT solver internals and will have a lecture format. Otherwise, the course will have a seminar format in which students will read and present papers on solver-aided languages (like [Dafny](https://rise4fun.com/Dafny/), [Liquid Haskell](https://ucsd-progsys.github.io/liquidhaskell-blog/), and [Rosette](https://emina.github.io/rosette/)), solver-aided systems (like [KLEE](https://klee.github.io/) and [Quelea](http://kcsrk.info/Quelea/)), and domain-specific solvers (like [Reluplex](https://arxiv.org/pdf/1702.01135.pdf)). The [readings page](readings.html) has the current schedule of readings. 36 | 37 | Some questions I want to explore include: 38 | 39 | - How does one design systems amenable to SMT-based verification? 40 | - Could solver-aided languages help us build solver-aided systems like Quelea? 41 | - Under what circumstances are off-the-shelf SMT solvers too big/blunt/slow of a hammer for a given problem? When should one build a custom solver as opposed to trying to find the right way to encode a problem for an existing solver? 42 | - How can we make it easier for domain experts to implement their own domain-specific solvers or solver extensions in high-level languages? Could (for instance) the Reluplex decision procedure be implemented in a high-level, "declarative" way and still be efficient? 43 | 44 | Students will be expected to carry out an independent research project of their own choosing that somehow fits with the course theme of SMT solving and solver-aided systems. 45 | 46 | ## Background you'll need 47 | 48 | This course has the UCSC graduate PL course CSE210A (formerly CMPS203) as a prerequisite. If you are interested in the topic but have not taken the prerequisite, I would nonetheless encourage you to take this course, as it will only be offered this one time. To request a permission code to register, or if you have other questions about the course, contact me at . 49 | 50 | Many of the papers we read will be what I'd classify as "PL papers". Although the ideas often aren't too complicated, there's a high notational overhead in many PL papers, and there are a few standard concepts you'll want to be familiar with. 51 | 52 | _At a minimum_, you should be familiar with the concepts in Jeremy Siek's ["Crash Course on Notation in Programming Language Theory"](http://siek.blogspot.com/2012/07/crash-course-on-notation-in-programming.html). Take some time to read it and brush up on anything you're not familiar with already. 53 | 54 | If you're not familiar with operational semantics of programming languages (or maybe even if you are!), watch [David Van Horn's excellent 45-minute tutorial video](https://www.youtube.com/watch?v=TU16mA5-i-g). 55 | 56 | Ask questions early when you come across notation you don't understand. If you're confused, you're probably not the only one! 57 | 58 | I won't assume any familiarity with SAT and SMT solver internals. We'll mostly assume that you are familiar with the basics of **propositional logic**, but if you need a refresher, look at [Chapter 1 (Propositional Logic) of _The Calculus of Computation: Decision Procedures with Applications to Verification_](https://link.springer.com/chapter/10.1007/978-3-540-74113-8_1) by Aaron R. Bradley and Zohar Manna ([off-campus access link](https://link-springer-com.oca.ucsc.edu/chapter/10.1007/978-3-540-74113-8_1)). 59 | 60 | ## Reading and responding to papers 61 | 62 | One goal of this course is to equip you to conduct research on SMT solvers and solver-aided systems by absorbing a lot of papers on the topic. 63 | 64 | One of the best ways to absorb reading material is to write about what you read. So, each student in the course will write a short response to each reading. 65 | 66 | ### What goes in a response? 67 | 68 | Responses should be in the ballpark of 500 words, which is about the minimum length that, say, a PLDI review should be. 69 | 70 | But we'll be reading stuff that has (with a few possible exceptions) already been thoroughly peer-reviewed. Your goal here is **not** to assess the quality of the papers. 71 | 72 | Rather, your goal is to construct a rich mental map of existing work, which you will sooner or later be able to use as a foundation for your own research. 73 | 74 | ### How to structure your response 75 | 76 | Try to structure your response around the following questions: 77 | 78 | 1. What's this paper about? (Summarize the paper and its contributions in your own words.) 79 | 2. What's one thing I learned? 80 | 3. What's something I didn't understand? 81 | 4. What's a research-level question I have after having read this paper? 82 | 5. What's a concrete step I can take toward answering the research question? 83 | 84 | A "research-level" question is something deeper than "What did the Greek letters on page 4 mean?" or "What's the baseline in Figure 6?" 85 | 86 | It might be something like, "The problem this paper addresses reminds me of the X problem, which is similar in ways A and B, but different in way C. Could this paper's approach, or something like it, be used to tackle X?" 87 | 88 | ### Further advice on how to read papers 89 | 90 | Reading research papers is a skill that requires practice. Attempting to plow right through from beginning to end is often not the most productive approach. Here's some great [advice from Manuel Blum on how to read and study](http://www.cs.cmu.edu/~mblum/research/pdf/grad.html): 91 | 92 | > Books are not scrolls. 93 | > Scrolls must be read like the Torah from one end to the other. 94 | > Books are random access -- a great innovation over scrolls. 95 | > Make use of this innovation! Do NOT feel obliged to read a book from beginning to end. 96 | > Permit yourself to open a book and start reading from anywhere. 97 | > In the case of mathematics or physics or anything especially hard, try to find something 98 | > anything that you can understand. 99 | > Read what you can. 100 | > Write in the margins. (You know how useful that can be.) 101 | > Next time you come back to that book, you'll be able to read more. 102 | > You can gradually learn extraordinarily hard things this way. 103 | 104 | You may also be interested in time-tested paper-reading advice [from Michael Mitzenmacher](https://www.eecs.harvard.edu/~michaelm/postscripts/ReadPaper.pdf) and [from S. Keshav](http://blizzard.cs.uwaterloo.ca/keshav/home/Papers/data/07/paper-reading.pdf). 105 | 106 | ### Response logistics 107 | 108 | Responses for each reading are due on Canvas **by noon on the day we discuss that reading in class** (see the [readings page](readings.md) for a schedule). There will be a Canvas assignment for each reading. Late responses will not be accepted. 109 | 110 | You do not have to submit a response for readings that you're presenting (more about presentations in a minute). 111 | 112 | _Free pass policy_: Because life throws unexpected challenges at each of us, you get three "free passes" to use during the quarter. Using a free pass exempts you from having to submit a response for one reading. If you want to use one of your free passes, just don't submit a response -- no need to email me. 113 | 114 | ## Presentations 115 | 116 | Each student will present at most two readings in class (the number could vary depending on how many students take the course and how many guest speakers we end up getting). 117 | 118 | Presentations should be about 35 minutes long, leaving about 25 minutes for discussion, which the presenter will lead. If you're the presenter, it's a good idea to have some suggested discussion questions to kick things off. (You do not need to have the answers!) 119 | 120 | The presentation format is up to you, but I suggest using slides unless you're confident of your blackboard skills. **You must email me a draft of your slides (or detailed notes, if not using slides) at least 24 hours before your presentation.** 121 | 122 | These presentations do not need to be highly polished performances, like conference talks do. Nevertheless, **take them seriously**. Don't show up with sloppy or incomplete slides or notes, and practice your presentation. 123 | 124 | **You must turn in a final copy of your slides or notes by EOD on the day you present**, either by emailing them to me (if you'd prefer not to make your materials public), or by uploading to [the `presentations` directory in our course repo](https://github.com/lkuper/CSE290Q-2019-09/tree/master/presentations). 125 | 126 | ### Choosing topics to present 127 | 128 | By next Monday, if you haven't done so yet, you should email me with a list of two to four [readings](readings.html) you'd like to present. I'll do my best to assign everyone the readings they want to present. 129 | 130 | If you have trouble coming up with two to four readings you want to present, pick from the ["further reading" section](readings.html#further-reading) instead; if there's enough interest in those readings, then we can promote them to the regular schedule. 131 | 132 | ### Advice on giving good talks 133 | 134 | You're here to do research, and as Simon Peyton Jones says, "Research is communication." Check out [his excellent advice](https://www.microsoft.com/en-us/research/academic-program/give-great-research-talk/) on how to give a great research talk; much of it is relevant for in-class presentations. 135 | 136 | Michael Ernst has [lots of good advice](https://homes.cs.washington.edu/~mernst/advice/giving-talk.html), too, including some specifically on giving in-class presentations. 137 | 138 | My most high-leverage tips: 139 | 140 | - Do the reading well in advance, and soak in it for a while. **Give yourself time to be confused.** 141 | - Don't present everything that's in the paper. Figure out what the big ideas are that you want to convey. What did you find the most interesting and important? What would you tell a good friend who asked you what the paper is about? 142 | 143 | ## Course project 144 | 145 | Every participant in the course will carry out an independent project. 146 | A project requires substantial work (some combination of reading, writing, editing, programming, debugging, and thinking). Expect to spend about 30-40 hours of focused work on the project over the course of the quarter. (Warning: **aim low**. 30-40 hours isn't actually that much time.) 147 | 148 | ### Project idea: The research investigation 149 | 150 | Dig into one of the research questions that you identify while writing your responses to the readings. 151 | 152 | Carry out one of the concrete steps toward answering it (which might involve writing code, measuring performance, writing proofs, and/or something else), and write about what you learn. 153 | 154 | Negative or inconclusive results are fine! 155 | 156 | ### Project idea: The literature survey 157 | 158 | Choose several (at least four, possibly many more) related readings that have something to do with the topic of the course, read them thoroughly, and write a survey paper analyzing them. 159 | 160 | At most one of your selected readings should be one we're already covering in class. The idea is to use something we read in class as a jumping-off point to go off on your own, explore the literature on a specific topic, and come back with new insights. 161 | 162 | Good sources of papers for a literature survey include the related work sections of things we read for class, or the ["further reading" section of the readings page](https://decomposition.al/CMPS290S-2018-09/readings.html#further-reading). 163 | 164 | ### Project idea: The experience report 165 | 166 | Try out one or more of the systems discussed in the readings, and report on your experience. 167 | 168 | For this kind of project, you should expect to write code. Aim higher than just "I got it to compile and run" -- ideally, you'll use the system to accomplish something cool, and report on what worked and what didn't. 169 | 170 | In many cases, it will be appropriate to try to reimplement a system from a paper we read, and reproduce the reported results. 171 | 172 | ### Project idea: Run someone's research 173 | 174 | Choose a "lightweight language mechanization" tool, such as [PLT Redex](https://redex.racket-lang.org/) or [the K framework](http://www.kframework.org/index.php/Main_Page), and use it to mechanize and test a language or system model from one of the readings you did. Report on what you learn from this process. 175 | 176 | There's a [good chance](https://eecs.northwestern.edu/~robby/lightweight-metatheory/popl2012-kcdeffmrtf.pdf) you'll find bugs or infelicities in the on-paper semantics! 177 | 178 | ### Project time frame 179 | 180 | - Friday, 11/1 EOD: Project proposals due. Submit an informal two-page writeup of the project you intend to do. You are encouraged to come talk to me about your project idea beforehand. 181 | - Monday, 11/18-Friday 11/22: Project status update week. Make a half-hour appointment to meet with me and show me what you've done on your project so far. No need to write anything up. Look at this as an opportunity to course-correct if your project is going sideways. 182 | - Wednesday, 12/4 and Friday, 12/6: In-class project presentations. Give a polished 15-minute presentation to the class about your work. 183 | - Friday, 12/6 EOD: Project reports due. Submit an 8-12 page writeup of your project (the most appropriate length will vary, depending on the project). You should be concerned about writing well; making your report a pleasure to read should be a priority. 184 | 185 | ## Grading 186 | 187 | - Responses to readings: 25% 188 | - Participation in class discussion: 20% 189 | - In-class reading presentations: 20% 190 | - Course project (includes project proposal, status update (i.e., you showed up and made an effort), in-class project presentation, and project report): 35% 191 | 192 | As you can see, participation is a big part of your grade -- so make an effort to come to class. 193 | 194 | If you must miss class on a given day, you can make up for it somewhat by reading your classmates' responses to that day's reading and leaving thoughtful comments on Canvas. (This shouldn't be necessary if you attend class, though.) 195 | 196 | ## Academic integrity 197 | 198 | This is a graduate seminar; you're expected and encouraged to discuss your work with others. 199 | 200 | That said, **everything you write for this course (paper summaries, blog posts, presentation materials, code, etc.) must be your own original work.** 201 | 202 | If you discuss a reading with others in order to write your response, add a note to your response giving the names of the people you discussed the reading with. 203 | 204 | **Properly attribute any work that you use.** For instance, if you make a slide that uses a figure created by someone else, then say so explicitly. 205 | 206 | It is part of your job as a scholar to understand [what counts as plagiarism](https://guides.library.ucsc.edu/citesources/plagiarism), and make sure you avoid it. 207 | 208 | ## Related courses 209 | 210 | A non-exhaustive list of courses at other institutions that have a good-sized overlap with this course's material: 211 | 212 | - Emina Torlak's [CSE 507: Computer-Aided Reasoning for Software](https://courses.cs.washington.edu/courses/cse507/19au/) at UW (see also [previous offerings](https://courses.cs.washington.edu/courses/cse507/) of the course) 213 | - [CS 357 Advanced Topics in Formal Methods](http://web.stanford.edu/class/cs357/) at Stanford 214 | - Marijn Heule and Ruben Martins's fall 2019 offering of [Advanced Topics in Logic: Automated Reasoning and Satisfiability](http://www.cs.cmu.edu/~mheule/15816-f19/index.html) at CMU 215 | - Işıl Dillig's [Automated Logical Reasoning](http://www.cs.utexas.edu/~isil/cs389L/) at UT Austin 216 | - Ranjit Jhala's spring 2013 offering of [CSE291: Algorithmic Software Verification](http://goto.ucsd.edu/~rjhala/classes/sp13/cse291/) at UCSD 217 | 218 | ## A note on accessibility 219 | 220 | If you have a disability and you require accommodations to achieve equal access in this course, please submit your Accommodation Authorization Letter from the [Disability Resource Center (DRC)](https://drc.ucsc.edu/index.html) to me privately during my office hours or by appointment, preferably within the first two weeks of the quarter. I am eager to discuss ways we can ensure your full participation in the course. 221 | 222 | I encourage all students who may benefit from learning more about DRC services to [contact the DRC](https://drc.ucsc.edu/about/contact-us/index.html). 223 | 224 | ## To do 225 | 226 | - **For Monday, September 30**: If you haven't yet done so, look over the [list of readings](readings.html), pick 2-4 papers that you'd like to present, and email me your choices. (If you don't pick, I'll pick for you.) 227 | - **For Monday, September 30**: Read the first reading assignment and submit your response on Canvas (remember that responses are due by noon on the day of class). 228 | -------------------------------------------------------------------------------- /decision-procedure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/decision-procedure.png -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "SMT Solving and Solver-Aided Systems" 3 | layout: single 4 | --- 5 | 6 |
7 | A decision procedure. 8 |
Drawing by Ilya Yodovsky Jr., from Decision Procedures: An Algorithmic Point of View by Daniel Kroening and Ofer Strichman
9 |
10 | 11 | Welcome to CSE290Q, fall 2019 edition! 12 | 13 | [SAT](https://dl.acm.org/citation.cfm?id=1536637) and [SMT](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories) solvers are now widely used across many areas of computer science, especially for automated software and hardware verification, but they are often "black boxes" to their users. This course is for those who want to look under the hood to learn how solvers work, and to explore a variety of systems that make use of them. 14 | 15 | For more information, read the [first-day-of-class course overview](course-overview.html), then check out the [reading list](readings.html). 16 | -------------------------------------------------------------------------------- /lecture-notes/2019-09-30-the-science-of-brute-force.md: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | documentclass: extarticle 4 | fontsize: 17pt 5 | mainfont: Helvetica 6 | mathfont: Helvetica 7 | --- 8 | 9 | # Lecture notes for: "The science of brute force" 10 | 11 | Lindsey Kuper 12 | 13 | September 30, 2019 14 | 15 | These are lecture notes to accompany Marijn J. H. Heule and Oliver Kullmann, "The science of brute force" (CACM 2017). See for the full collection of notes. 16 | 17 | ## Agenda 18 | 19 | - Motivating problem #1: Pythagorean triples problem 20 | - Why we care 21 | - Motivating problem #2: Boolean Schur triples problem 22 | - SAT solving terminology 23 | - Solver internals: paradigms of SAT solving, CDCL, BCP 24 | - Illustrating CDCL and BCP: back to Boolean Schur Triples 25 | - Who watches the watchmen? 26 | 27 | ## Welcome to CSE290Q 28 | 29 | So, I could have just gone right to the Kroening and Strichman textbook, but I decided to have us start by reading this "Science of Brute Force" article because I thought that might be a little more fun and less dry than the textbook --- the article has some colorful language (like "A mathematician using 'brute force' is a kind of barbaric monster, is she not?") Maybe you found it fun, maybe you didn't. 30 | 31 | This article also introduces a few concepts that we'll be spending time in the next few weeks talking about in much more detail. And it does that by setting up a math problem and then discussing, at least at a high level, the techniques by which a SAT solver would solve that problem. I think this is instructive and so we'll actually walk through that math problem today. 32 | 33 | We won't really be talking about the last third or so of the article: 34 | 35 | - Details of "solutions-preserving modulo x" 36 | - The Ramsey theory stuff 37 | - Philosophical musings about "alien truths" 38 | 39 | But I might have time to talk about that stuff some more on Wednesday. 40 | 41 | By the way, this course is mostly about SMT solving, right? Why did I have us start out reading an article about SAT? Well, SAT solving is at the heart of SMT solving, as we'll see. Or you could also say that SAT solving *is* SMT solving; it's just the degenerate case where the theory, "T", is the boring default one. More about that in the coming weeks. 42 | 43 | ## Motivating problem #1: Pythagorean triples problem 44 | 45 | Consider all partitions of the set of natural numbers into finitely many parts. (At least one part has to be infinite, then.) 46 | 47 | The question: does at least one part contain a Pythagorean triple, that is, numbers $a, b, c$ such that $a^2 + b^2 = c^2$? 48 | 49 | For instance, say we partition the natural numbers into just two parts: odd numbers and even numbers. 50 | 51 | It turns out that the square of an odd number is always odd (since $(2k + 1)(2k + 1) = 4k^2 + 4k + 1$). But adding two odd numbers will produce an even number. So there can't be a Pythagorean triple in the odd partition. But the even partition does have one: $6^2 + 8^2 = 10^2$. 52 | 53 | ### Simplified problem 54 | 55 | Well, that was one way to split up the set of natural numbers into two parts. What about other ways of splitting into two parts? Is there always going to be a Pythagorean triple in at least one of the parts? 56 | 57 | They show that the answer is yes. This is the "Boolean Pythagorean triples" problem. (If it were "three parts" that would be the "three-valued Pythagorean triples" problem.) 58 | 59 | It suffices to show the existence of a *subset* of the natural numbers such that any partition of that subset into two parts has one part containing a Pythagorean triple. 60 | 61 | Consider only subsets $\{1, ..., n\}$ for some $n$. It turns out (via a brute force proof using a SAT solver) that the smallest such subset for which the property is true is $\{1, 2, 3, ..., 7825\}$. 62 | 63 | How many ways are there to partition the set $\{1, 2, 3, ..., 7825\}$ into two parts? 64 | 65 | - 1 can go in set 1 or set 2 (2 ways) 66 | - 2 can go in set 1 or set 2 (4 ways) 67 | - ... 68 | - 7825 can go in set 1 or set 2 ($2^{7825}$ ways) 69 | 70 | So there are $2^{7825}$ ways to partition the set $\{1, 2, 3, ..., 7825\}$ into two parts. How big a number is $2^{7825}$? "Way too big." At least, way too big to deal with without a computer. 71 | 72 | No non-computational existence proof for this problem is known --- that is, the *only* way we know to solve this problem is with something like a SAT solver. 73 | 74 | ### How far are we from being able to solve the full Pythagorean triples problem? 75 | 76 | We did the case of two parts; how about three? We can show that the set $\{1, 2, ..., 10^7\}$ can be partitioned into three parts such that *no part* contains a Pythagorean triple. So, if there is some $n$ such that every 3-partitioning of $n$ has a part containing a Pythagorean triple, we know that $n > 10^7$. 77 | 78 | How many ways are there to partition the set $\{1, 2, ..., 10^7\}$ into three parts? 79 | 80 | - 1 can go in set 1, set 2, or set 3 (3 ways) 81 | - 2 can go in set 1, set 2, or set 3 (9 ways) 82 | - ... 83 | - $10^7$ can go in set 1, set 2, or set 3 ($3^{10^7}$ ways) 84 | 85 | So there are $3^{10^7}$ ways to partition the set $\{1, 2, ..., 10^7\}$ into three parts. This number is so big that we might not ever solve the three-valued Pythagorean triples problem. 86 | 87 | And the problem we originally started with, when it was any finite number of parts --- well, good luck. 88 | 89 | ## Why do we care? 90 | 91 | Why are we playing these games? Because solving these problems is analogous to the problems we face in software verification and automated bug-finding. 92 | 93 | - Bug-finding is finding counterexamples. "Finding a bug in a large hardware system is essentially the same as finding a partition avoiding all Pythagorean triples." (If you don't find one, it doesn't mean there isn't one, but if you do find one, it is definitely there.) 94 | 95 | - Verification is proving that there is no counterexample. "Proving correctness [of a large hardware system]...is similar to proving that each partition must contain some Pythagorean triple." 96 | 97 | The focus of most of this course is on using solvers for automated software bug-finding and verification. So this article is honestly doing something sort of quaint by using them for mathematical proofs, instead. Like, "More secure and reliable software? Who cares about that? Let's just do math problems for their own sake!" But I still think the article is very helpful for helping us understand how one goes about encoding a problem as a SAT problem, and then how the solver goes about solving it. 98 | 99 | (BTW, SAT is perhaps even more important for _hardware_ verification than it is for software verification. The article claims, "SAT has revolutionized hardware verification." "Bounded model checking using satisfiability solving" by Edmund Clarke et al. (2001) is the citation for that claim. I'm actually not sure how much that paper has to do with hardware, but it's a good one to look at if you want to know about the relationship between model checking and SAT solving.) 100 | 101 | ### BTW, what is model checking? 102 | 103 | This is a diversion, but maybe worth knowing about because it overlaps with studying SAT and SMT, and I myself didn't know this until recently. 104 | 105 | So, a piece of hardware or software can be modeled as a finite-state machine. If you've taken a theory of computation class then you know about finite state machines. (The Clarke et al. paper talks about "transition systems", which are a generalization of finite state machines.) Model checking means exhaustively exploring the state space of a system to check whether a certain property is true. So for instance, suppose you want to make sure that some property is always true. Well, you exhaustively go through every state that the system can be in, and you check that it's true in every state. One particularly effective way of doing this is using satisfiability solvers. 106 | 107 | ## Motivating problem #2: Boolean Schur triples problem 108 | 109 | So at this point they switch problems to a different problem, which is related, but small enough to actually work out ourselves. 110 | 111 | So, the "Boolean Schur triples problem": Does there exist a red/blue coloring of the numbers $1, ..., n$ such that there is *no monochromatic solution* of $a + b = c$ with $a < b < c \leq n$? 112 | 113 | (A "Schur triple" is just any three numbers $(a, b, c)$ where $a + b = c$. The "Boolean" in the name of the problem here just refers to the fact that there are two color options, red and blue.) 114 | 115 | So this time we're dealing with all natural numbers, not just squares of natural numbers. 116 | 117 | For $n = 8$, such a coloring exists. Anyone remember what it was from the paper? 118 | 119 | To spill the beans: color 1, 2, 4, 8 red, and color 3, 5, 6, 7 blue. 120 | 121 | So how would you have solved this in a naive brute-force way? 122 | 123 | Well, there are two ways to color each number, right? Red and blue. So, with 8 numbers, that's $2^8$ possibilities. How many is that? 256. And then for each possibility (say, 1 red and 2-8 all blue), you have to go through and consider each subset of 3 numbers a, b, c, where $a + b = c$, and make sure that a, b, and c weren't all colored the same color. 124 | 125 | Or maybe you would pick out all subsets of three numbers that *are* the same color, and then make sure that two of them don't add up to the remaining one. I dunno. 126 | 127 | This is not necessarily the most efficient way to solve the problem, though. What if you could avoid having to go through all 256 colorings? 128 | 129 | In the paper they show how for $n = 9$, there's no way to do the coloring, and they figure this out without having to consider all $2^9 = 512$ possible red/blue colorings. In fact, they say that with "brute reasoning" (which I think of as meaning "brute force, but employed in a clever way"), only six (partial) red/blue colorings even need to be checked. We'll look at a SAT encoding of this problem and come back to why you only need to check six colorings in a bit. 130 | 131 | ## SAT solving terminology 132 | 133 | So let's finally talk about SAT solving, and to do that we have to define some terms. 134 | 135 | - A "Boolean variable" can be assigned either true or false. 136 | 137 | - A "literal" is either a Boolean variable or its negation. So if $x$ is a Boolean variable, then $x$ is a literal, and so is $\neg x$. 138 | 139 | - A literal $x$ is true if the Boolean variable $x$ is assigned to true; a literal $\neg x$ is true if the Boolean variable $x$ is assigned to false. (Sometimes we abuse terminology by talking about "assigning to a literal", when it's only variables that can be assigned to.) 140 | 141 | - A "clause" is a disjunction of literals, that is literals connected by an "or". So if $x$ and $y$ are Boolean variables, then $x \lor y$ is a clause, and so is $x \lor \neg y \lor z$, and so on. A single literal by itself is also a clause. 142 | 143 | - A "SAT formula" is a conjunction of clauses. So $(x \lor y) \land (\neg z \lor q)$ is a SAT formula. This is called conjunctive normal form (CNF): a formula is in CNF if it is a conjunction of clauses (or a single clause). 144 | 145 | - An "assignment" is a mapping of each Boolean variable in a SAT formula to either true or false. The reading says: A clause is satisfied by an assignment if that assignment makes at least one of its literals true. A formula is satisfied by an assignment if all of its clauses are satisfied. (BTW, an assignment is also called an "interpretation" of the variables.) 146 | 147 | - A SAT formula is "satisfiable" if there exists *some* satisfying assignment for it, and "unsatisfiable" if there does not exist any satisfying assignment. 148 | 149 | - "solving" a SAT formula is determining its satisfiability or unsatisfiability. 150 | 151 | - A "SAT solver" is a computer program that solves SAT formulas. 152 | 153 | **Q:** So, for instance, is $(x \lor \neg y) \land (\neg x \lor y)$ satisfiable? 154 | 155 | A: Yes. What are the satisfying assignments? x = true, y = true is one; the other is x = false, y = false. 156 | 157 | **Q:** How computationally hard is SAT? 158 | 159 | A: Satisfiability of general Boolean formulas is a famously NP-complete problem. In fact, it was the first problem proven to be NP-complete, in 1971. There's no known polynomial-time algorithm for solving the SAT problem, and the question of whether SAT has a polynomial-time algorithm is equivalent to the P versus NP problem. 160 | 161 | But the silver lining of NP-completeness (and the paper makes sure to point this out) is that any problem in NP can be efficiently converted to SAT. This is why SAT solvers are so damn useful, because a whole lot of interesting computational problems (especially software and hardware verification) can be converted to SAT, and then you can throw a SAT solver at them. 162 | 163 | Practically though; speaking, modern SAT solvers often do a good job on really big formulas. You might have heard people talk about the so-called "SAT revolution" or "SMT revolution". In the early 90s, solvers could handle formulas with thousands of clauses; today, solvers can handle formulas with millions of clauses. 164 | 165 | Also, just as an aside: if the formula is a conjunction of clauses and the clauses are each a disjunction of exactly two literals, then that's known as a 2SAT formula, and these *are* solvable in polynomial time! (Look up 2-satisfiability on Wikipedia to learn lots more about this.) However, this isn't helpful unless you have clauses that are each a disjunction of exactly two literals. 166 | 167 | ## Solver internals: CDCL, BCP 168 | 169 | The article mentions three "paradigms of SAT solving", and I like the article's description of these, so I'm just going to reproduce it here. 170 | 171 | - "local search": incomplete; tries to find a solution via local modifications to total assignments 172 | 173 | What does incomplete mean? It means if you give it a formula, it can only find satisfying assignments to the formula, but it cannot tell you for sure if the formula is unsatisfiable. 174 | 175 | So it's "sound", meaning that if it tells you a satisfying assignment, then you know that that really is a satisfying assignment. But it's incomplete, meaning that if it doesn't give you a satisfying assignment, that doesn't mean that there isn't one! So the answers you get back from local search are either "yes, here is a satisfying assignment" or "shrug". 176 | 177 | - "look-ahead": complete; recursively splits the problem as cleverly as possible into subproblems 178 | - "conflict-driven clause learning" (CDCL): complete; tries to assign variables to find a satisfying assignment, and if that fails (the normal case), then the failure is transformed into a clause called a "conflict clause" which is added to the formula you're trying to satisfy. (This is what "clause learning" means.) 179 | 180 | These two paradigms are both sound and complete. If it doesn't give you a satisfying assignment, you know that there is not one. The answers you get back are either "yes, here is a satisfying assignment" or "no, there is no satisfying assignment". 181 | 182 | ### CDCL 183 | 184 | OK, so what is CDCL? BTW, if you've heard of DPLL, CDCL is the successor to it. DPLL is the grandaddy of SAT solving algorithms and has been around since the '60s; CDCL is the modern successor to DPLL. (There'll be more on this in a future reading assignment.) 185 | 186 | OK, so, CDCL at a very high level (we'll go into more detail on the CDCL algorithm in the coming days): 187 | 188 | Three phases: simplify, decide, learn. 189 | 190 | - simplify: simplify the formula you have and update the assignment with any new inferences you learn. (We'll see an example of this in a second.) 191 | - decide: pick an unassigned variable and assign it true or false, using some heuristic. The heuristics that you use here are called, unsurprisingly, "decision heuristics". 192 | 193 | **Q:** What's a heuristic, by the way? 194 | 195 | A: A heuristic is an approach that's "fast enough" and "good enough" that we use when we don't necessarily know the optimal thing to do. Heuristics usually have some pathological case that goes wrong. 196 | 197 | The article mentions a couple of kinds of these decision heuristics, but we're not really going to talk about that today at all; we'll read about it in the coming weeks. At a high level, though, the idea is that you have to somehow choose which variable to assign to, and you have to choose what to assign to it. Making a good decision early on can make solving the whole problem faster. 198 | 199 | OK, so you iterate these two phases until one of two things happen: 200 | 201 | - you have a satisfying assignment (yay, you're done). 202 | - at least one clause has been falsified --- you made a mistake somewhere. 203 | 204 | In the "you made a mistake" case, you've created what's called a "conflict". You need to learn from your mistake and make sure you don't make it again in the future. So, you go to the "learn" phase: 205 | 206 | - learn: add a new clause called a "conflict clause" to the formula. The point of the "conflict clause" is to prevent the decide phase from making that particular mistake again, i.e., prevent the solver from trying that particular assignment again. We'll see an example of what a conflict clause looks like in a little while. Then you backtrack to before you made the mistake, and you go back up to the simplify/decide cycle and keep going. 207 | 208 | **Q:** OK, so what about unsatisfiability? What if your formula is unsatisfiable --- when do you find that out? 209 | 210 | A: During the learn phase. It turns out that if the new "conflict clause" you're forced to add is what's called the "empty clause", which is a clause that can't be satisfied, that means that you have an unsatisfiable formula (yay, you're done). 211 | 212 | That's a very high-level overview of CDCL. It's OK if it doesn't make sense now; we'll talk about this a lot more when we read chapter 2 of the Kroening and Strichman book. 213 | 214 | Unanswered question: in the decide phase, what heuristics do you use to pick an unassigned variable and assign it? We'll come back to this later in the course. 215 | 216 | ### BCP 217 | 218 | What this article calls "unit clause propagation" (UCP) is also known as "unit propagation" or "Boolean constraint propagation" (BCP). I'll use the term BCP because I think it's more common. 219 | 220 | BCP is a part of the CDCL algorithm. This is again something we'll study more later, but let's talk about it really quick: 221 | 222 | Recall that a clause is a disjunction of literals. So the way to satisfy a clause is to make at least one of its literals true. 223 | 224 | A clause is "unit" under a partial assignment that makes all but one of its literals false, and leaves one unassigned. The only way to satisfy a unit clause under that partial assignment is to assign the necessary value to make the remaining literal true. 225 | 226 | So, if you have a partial assignment and a formula, and the formula has unit clauses, then you go through the unit clauses and add to the assignment by assigning variables to satisfy the unit clauses. This is what's known as Boolean constraint propagation. There are two possibilities: 227 | 228 | - you've satisfied all the unit clauses 229 | - you've created a conflict, because two unit clauses contradict each other (one has a literal $x$, and the other has $\neg x$) 230 | 231 | If you created a conflict, you then have to deal with the conflict. We'll talk about this more soon, but at a high level, one of two things will happen: 232 | 233 | - you have to backtrack and do something different 234 | - you figure out that the formula is unsatisfiable 235 | 236 | **Q:** If a formula has a unary clause to begin with, is it a unit clause? 237 | 238 | A: Yep. So you should do BCP right away, even before you make any decisions. 239 | 240 | ## Illustrating CDCL and BCP: back to Boolean Schur triples 241 | 242 | Let's see an example of CDCL and BCP in action. 243 | 244 | So, back to the Boolean Schur triple problem: Does there exist a red/blue coloring of the numbers 1, ..., n such that there is *no monochromatic solution* of a + b = c with $a < b < c \leq n$? 245 | 246 | We're thinking about the case where n = 9. 247 | 248 | First step is to encode this problem as a SAT problem. 249 | 250 | They encode it this way: 251 | 252 | Enumerate all the ways where a + b = c where a, b, and c are drawn from the set 1, ..., 9, and a < b < c <= n. 253 | 254 | There turn out to be 16 of these: 255 | 256 | - 1 + 2 = 3 257 | - 1 + 3 = 4 258 | - 1 + 4 = 5 259 | - 2 + 3 = 5 260 | - 1 + 5 = 6 261 | - 2 + 4 = 6 262 | - 1 + 6 = 7 263 | - 2 + 5 = 7 264 | - 3 + 4 = 7 265 | - 1 + 7 = 8 266 | - 2 + 6 = 8 267 | - 3 + 5 = 8 268 | - 1 + 8 = 9 269 | - 2 + 7 = 9 270 | - 3 + 6 = 9 271 | - 4 + 5 = 9 272 | 273 | So our triples are (1, 2, 3), (1, 3, 4), ... (4, 5, 9). And we want to show that there is a way to color each of the numbers 1, ..., 9 either red and blue in such a way that all of these triples have some red and some blue in them. In other words, at least one number in each triple has to be red, and at least one number in each triple has to be blue. 274 | 275 | We have 9 Boolean variables, $x_1$, $x_2$, ..., $x_9$, representing each of the numbers 1 through 9, respectively. We'll encode red as true and blue as false. 276 | 277 | And then we just write out two clauses for each of the 16 triples. One clause will say that at least one of the numbers has to be red, so, for the triple (1, 2, 3), for instance, we have the clause $(x_1 \lor x_2 \lor x_3)$. And one will say that at least one of the numbers has to be blue, so, again for (1, 2, 3), we have the clause $(\neg x_1 \lor \neg x_2 \lor \neg x_3)$. 278 | 279 | And the formula is just the conjunction of all of these clauses. So if this formula is satisfiable, then we have a red/blue coloring that satisfies the property, and if it isn't, then we don't. 280 | 281 | There are, as we said before, $2^9 = 512$ possible assignments of true and false to the variables. But we said that you actually only have to check six of them. 282 | 283 | So what do they do? Well, let's look at $x_1$ first. It has two possibilities, false and true. 284 | 285 | \begin{minipage}{\linewidth} 286 | \begin{verbatim} 287 | x1 288 | / \ 289 | f t 290 | \end{verbatim} 291 | \end{minipage} 292 | 293 | In the world where $x_1$ is false, then let's think about $x_3$. Say that it's false. 294 | 295 | \begin{minipage}{\linewidth} 296 | \begin{verbatim} 297 | x1 298 | / \ 299 | f t 300 | | 301 | x3 302 | / 303 | f 304 | \end{verbatim} 305 | \end{minipage} 306 | 307 | OK, so $x_1$ is false and $x_3$ is false. Well, now we can do BCP! 308 | 309 | Well, it says that $x_2$ has to be true, because $x_1$, $x_2$, and $x_3$ are in a clause together. 310 | And it says that $x_4$ has to be true, because $x_1$, $x_3$, and $x_4$ are in a clause together. 311 | 312 | So $x_2$ and $x_4$ have to be true, but then they're in a triple with $x_6$, so $x_6$ has to be false. 313 | 314 | But $x_1$ and $x_6$ are in a triple with $x_7$, so then $x_7$ has to be true. 315 | And $x_3$ and $x_6$ are in a triple with $x_9$, so then $x_9$ has to be true. 316 | 317 | But now we have a conflict because all of $x_2$, $x_7$, and $x_9$ are now true and they're in a triple together. In other words, the part of our formula that says $(\neg x_2 \lor \neg x_7 \lor \neg x_9)$ is now unsatisfiable. 318 | 319 | So we've just ruled out all assignments where both $x_1$ and $x_3$ are false, regardless of the other settings. (That's a lot of assignments.) 320 | 321 | What do we do now? Well, we know that one of $x_1$ and $x_3$ have to be true, right? So now we've learned our first conflict clause! The conflict clause will be $(x_1 \lor x_3)$. Then we go back to before we set $x_3$ to true, and try something else. 322 | 323 | So now consider the case where $x_1$ is false but $x_3$ is true. No conflicts yet, so then we can go a little deeper. Consider $x_5$. Let's say it's false. 324 | 325 | What does that tell us? Once again, we can do BCP. 326 | 327 | It says that $x_4$ has to be true, because $x_1$, $x_4$, and $x_5$ are in a clause together. 328 | And it says that $x_6$ has to be true, because $x_1$, $x_5$, and $x_6$ are in a clause together. 329 | 330 | So then $x_2$ has to be false, because $x_2$, $x_4$, and $x_6$ are in a triple together. 331 | and since $x_5$ is false, and $x_2$, $x_5$, and $x_7$ are in a triple together, $x_7$ has to be true. 332 | But now $x_3$ is true, $x_4$ is true, and $x_7$ is true, and they're in a triple together. 333 | 334 | So we've just ruled out all assignments where $x_1$ is false, $x_3$ is true, and $x_5$ is false. We already know that one of $x_1$ and $x_3$ has to be true. So now we know that $x_1$ and $x_5$ can't be false at the same time, because if $x_1$ is false, then $x_3$ has to be true. 335 | 336 | So we've learned another conflict clause: $(x_1 \lor x_5)$. 337 | 338 | And so on. It turns out we can keep applying similar reasoning to this, and we end up only having to consider six partial assignments to show that the formula is unsatisfiable. 339 | 340 | \begin{minipage}{\linewidth} 341 | \begin{verbatim} 342 | x1 343 | / \ 344 | / \ 345 | / \ 346 | / \ 347 | / \ 348 | f t 349 | | | 350 | x3 x3 351 | / \ / \ 352 | f t f t 353 | | | 354 | x5 x5 355 | / \ / \ 356 | f t f t 357 | \end{verbatim} 358 | \end{minipage} 359 | 360 | So let's back up a second. That worked out pretty well for us, but the whole reason why it worked out so well was because we looked at $x_1$ first, and then looked at $x_3$, and so on. If we had looked at the variables in a different order, we might not have been able to rule out huge chunks of the search space so fast. 361 | 362 | **Q:** So how did I know to look at $x_1$ first, and then $x_3$, and so on? 363 | 364 | A: Using a simple heuristic --- the "Maximum Occurrences in clauses of Minimal Size" heuristic, known affectionately as "MOMS". 365 | 366 | When we start, all the clauses are of the same size, and $x_1$ occurs the most. So we start with $x_1$. Then, after simplification, $x_3$ occurs the most in clauses of minimal size, and so on. It turns out that this simple heuristic is enough to cut the number of partial assignments that need to be checked down to 6. 367 | 368 | They point out that for the original problem that they talked about, the Pythagorean Triples problem, this simple heuristic isn't enough, and in fact the authors of this paper had to design a special, fancy heuristic just for solving that problem. They cite their own paper about that. 369 | 370 | ## Who watches the watchmen? 371 | 372 | Do you trust a SAT solver that claims a problem is unsatisfiable? 373 | 374 | If a solver says a formula is satisfiable, that's one thing. The solver will provide a satisfying assignment, and it's easy to check that the assignment actually does satisfy the formula. 375 | 376 | But, if a solver says a formula is _unsatisfiable_, like in the Boolean Schur triples problem instance that we just talked about, how do you know it's correct? Especially if it's a solver using some special, fancy heuristic, how do you know you can trust it? 377 | 378 | Well, you could formally verify the SAT solver itself. But that's really hard to do. And most people are going to want to use their fast SAT solver of choice, not the not-necessarily-state-of-the-art verified one. 379 | 380 | The other idea is to have the solver produce a "certificate" of an unsatisfiability claim, or a _proof of unsatisfiability_. It then needs to be possible to quickly and automatically _validate_ the proof, that is, make sure that it actually does certify unsatisfiability. 381 | 382 | What does such a proof of unsatisfiability look like? The article discusses one technique for creating them. The idea is this: to determine unsatisfiability of the formula, we had to deduce a whole bunch of these conflict clauses, right? So, we should be able to make sure that the solver did the right thing by making sure that each conflict clause was deduced correctly. This is called a _clausal proof_ of unsatisfiability. 383 | 384 | Adding a new clause to the forumla you're trying to determine the satisfiability or unsatisfiability of is a risky thing, right? 385 | 386 | **Q:** What property do you want to have be true when you add a clause? 387 | 388 | A: Well, you want to make sure that you don't *change* the satisfiability of the formula by adding a clause. In other words, you want the addition of a clause to be "solutions-preserving": any satisfying assignments that there were for the previous formula should also satisfied by the new formula with the added clause. 389 | 390 | It turns out that this is actually pretty easy to check, though. If you have a formula F and you want to know that a new clause C is solutions-preserving, just take the partial assignment that makes all literals in C false. Then do BCP on F with that assignment. If you get a conflict, then you know that the clause is solutions-preserving, since you now know that it's not possible to falsify C and also satisfy F. 391 | 392 | So, to check a proof of unsatisfiability, we just need a list of all the clauses that were learned and added, and then we use BCP to check the proof. It's surprisingly straightforward! 393 | 394 | We don't have time to go into more detail about this, but the citation for this if you want to know more is "Verification of Proofs of Unsatisfiability for CNF Formulas" by Goldberg and Novikov (2003). The paper is only six pages long. 395 | 396 | There's more stuff in the article about what it means to be solutions-preserving modulo a particular variable, but we don't have time to get into that. 397 | -------------------------------------------------------------------------------- /lecture-notes/2019-09-30-the-science-of-brute-force.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/lecture-notes/2019-09-30-the-science-of-brute-force.pdf -------------------------------------------------------------------------------- /lecture-notes/2019-10-02-introduction-to-decision-procedures-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | documentclass: extarticle 4 | fontsize: 17pt 5 | mainfont: Helvetica 6 | mathfont: Helvetica 7 | --- 8 | 9 | \newcommand{\satisfies}{\vDash} 10 | 11 | # Lecture notes for: Introduction to decision procedures, part 1 12 | 13 | Lindsey Kuper 14 | 15 | October 2, 2019 16 | 17 | These are lecture notes to accompany sections 1.0-1.3 (pp. 1-14) of Kroening and Strichman's _Decision Procedures: An Algorithmic Point of View_, second edition. See for the full collection of notes. 18 | 19 | ## Agenda 20 | 21 | - What's a theory (informally)? 22 | - More terminology 23 | - Soundness and completeness; decidability 24 | - Normal forms 25 | 26 | ## What's a theory (informally)? 27 | 28 | So, this course is about SMT solving, and the T in SMT stands for "theories". What is a theory? 29 | 30 | We haven't defined this formally yet, and we aren't going to right now. But, informally, it's **the language that formulas can be written in.** 31 | 32 | So, last time we looked at SAT formulas, like $x_1 \lor (x_2 \lor \neg x_3)$. When you're just talking about SAT solving, which is all we talked about last time, you're only concerned with formulas that look like this. 33 | 34 | These SAT formulas are also called **propositional logic** formulas (I'll interchangeably say "SAT formula" and "propositional logic formula" in this course). Propositional logic is the simplest theory. The formulas are built out of Boolean variables, conjunction ($\land$), disjunction ($\lor$), negation ($\neg$), and parentheses. So the inductive definition of a formula is: 35 | - a Boolean variable by itself is a formula (we call this an "atomic formula" or just an "atom") 36 | - if $\phi$ is a formula, then $\neg\phi$ is a formula 37 | - if $\phi_1$ and $\phi_2$ are formulas, then $(\phi_1 \land \phi_2)$ is a formula 38 | - if $\phi_1$ and $\phi_2$ are formulas, then $(\phi_1 \lor \phi_2)$ is a formula 39 | 40 | (If we followed these rules to the letter, then we would need to put more parentheses in, but the usual convention is to omit a lot of the parentheses and assume a certain order of operations.) 41 | 42 | Also, this doesn't say anything about being in CNF, but every propositional logic formula can be rewritten in CNF, so we usually just assume CNF. Last time, when we talked about SAT formulas we assumed they were in CNF. 43 | 44 | So, propositional logic is one theory. But what if we want to have formulas with more _stuff_ in them? Here's one example from the book: 45 | 46 | $y_1 = y_2 \land \neg(y_1 = y_3) \Longrightarrow \neg(y_2 = y_3)$ 47 | 48 | What did we add to the language that formulas can be written in? Well, we have a couple of new symbols: implication and equals. We haven't said anything about the domain that the variables come from; are they still Boolean variables like in propositional logic, or could they be something else, like numbers? We'll talk more about that later. 49 | 50 | So this formula is from the "theory of equality", or "equality logic". It's perhaps not all that exciting of a theory, since it turns out that it's not any more expressive than the theory of propositional logic. But it might allow for a more natural way to encode some problems. 51 | 52 | Here's another formula: 53 | 54 | $2z_1 + 3z_2 \leq 5 \land z_2 + 5z_2 - 10z_3 \geq 6$ 55 | 56 | So now there's a lot more stuff. We have *in*equalities; we have numbers; we've got addition and subtraction. It looks like our variables definitely come from some sort of domain of numbers now. This is what's called a *linear arithmetic* formula. 57 | 58 | The "linear" in linear arithmetic refers to the fact that you're not allowed to multiply variables with each other. You can only add or subtract them. 59 | 60 | Again, we haven't said what domain the variables come from. But if they come from the domain of real numbers, then we have what's often called the theory of linear real arithmetic. If they come from the domain of integers, that's often called the theory of linear integer arithmetic. Sometimes it's also called the theory of Presburger arithmetic. 61 | 62 | Believe it or not, these kinds of formulas can be converted to plain old boring SAT formulas and then solved with a SAT solver. (A citation for this is "On Solving Presburger and Linear Arithmetic with SAT" (Ofer Strichman, 2002). Even though it makes sense that one decidable theory can be converted to another, simpler decidable theory --- in the same way that any programming language can be compiled to machine language --- it's still kind of mind-blowing to me that it's possible.) But that is not, in fact, what most solvers do. We'll talk more about this more as we get further along in the book. 63 | 64 | So, I'm listing all these off not because I want to talk about any of the details of these theories today, because I don't want to do that today, but simply because I want to give you some kind of intuition for what a theory is, and introduce you to the idea that when I talk about a "formula", it may not necessarily be a propositional logic formula, like the formulas we talked about on Monday, but it may in fact be a formula that comes from some other theory. 65 | 66 | So we're going to define some more terms, and they'll overlap with terms that we defined last time, but some of the definitions will be more general now, because now we're talking about arbitrary formulas and not necessarily just propositional logic formulas. 67 | 68 | ## More terminology 69 | 70 | I mentioned before that a Boolean variable by itself is an "atom" in propositional logic. In general, regardless of the theory, an "atom" is a formula with no propositional structure. That is, it doesn't contain any $\land$, $\lor$, or $\neg$ connectives. 71 | 72 | So, in the propositional logic formula $x \lor \neg y$, $x$ and $y$ are atoms. But in an equality logic formula, like $y_1 = y_2 \lor \neg(y_1 = y_3)$, the atoms are the equalities $y_1 = y_2$ and $y_1 = y_3$. So, the atoms of a formula depend on the theory. 73 | 74 | This means we can also generalize another of our definitions from last time. Last time we said a "literal" is either a Boolean variable or its negation. That's the case for propositional logic, but in general, a literal is either an atom or its negation. So, $y_1 = y_2$ and $\neg(y_1 = y_3)$ are the literals in the aforementioned formula. 75 | 76 | Last time we said that an "assignment" is a mapping of each Boolean variable in a SAT formula to either true or false. We can generalize that one, too. Say we have a formula, call it $\phi$, from some theory -- doesn't matter which one. We can now say that: 77 | 78 | - an "assignment" of $\phi$ *from a domain $D$* is a mapping of $\phi$'s variables to elements of $D$. So, if $D$ is the integers, maybe an assignment would be like x = 1, y = -3. 79 | 80 | - If the assignment gives mappings for all of the variables in the formula, it's a "full" assignment of that formula, and otherwise it's a "partial" assignment of the formula. 81 | 82 | - And just like yesterday, a formula is "satisfiable" if there is some assignment that makes the formula evaluate to true, and "unsatisfiable" otherwise. 83 | 84 | So this is all the same as yesterday, it's just that now the domain can be something other than just true and false. 85 | 86 | **Q:** What do we call it when the formula is satisfied by *every* assignment? 87 | 88 | A: Then we say that the formula is "valid" or a "tautology". 89 | 90 | **Q:** What's the relationship between satisfiability and validity? 91 | 92 | A formula $\phi$ is valid if and only if $\neg\phi$ is unsatisfiable. Which is convenient, because you can check the validity of a formula by checking if its negation is unsatisfiable. 93 | 94 | So, if I have a validity checker, and I want to know the satisfiability of a formula, I just negate the formula and run the validity checker on the negated formula. If the answer I get back is "valid", then the formula was unsatisfiable, and if the answer I get back is "not valid", then the formula was satisfiable. 95 | 96 | Conversely, if I have a satisfiability checker, and I want to know the validity of the formula, again, I just negate the formula and run the satisfiability checker on it. If the answer I get back is "unsatisfiable", then the formula is valid. If the answer I get back is "satisfiable", then the formula is not valid. 97 | 98 | So, validity checking and satisfiability checking are interchangeable, in the sense that if you can do one then you can trivially do the other. 99 | 100 | If we have an assignment, call it $\alpha$, that satisfies a formula $\phi$, then we write $\alpha \satisfies \phi$. You can pronounce this "$\alpha$ satisifies $\phi$". If "$\phi$" is satisfied by every assignment --- in other words, if $\phi$ is valid --- then we can just write $\satisfies \phi$ and leave off the $\alpha$ part. 101 | 102 | **Q:** Should anything that I said just now give you pause, now that we're talking about arbitrary formulas and not just plain old SAT formulas? 103 | 104 | A: Yes. The word "evaluate" should give you pause! We already know how to "evaluate" a propositional logic formula, because we can write down a truth table that tells us what the propositional logic connectives mean. And we said last time that "solving" a SAT formula is determining its satisfiability or unsatisfiability, and a "SAT solver" is a computer program that solves SAT formulas. SAT solvers use CDCL and fancy heuristics, but we could also do it on paper with a truth table, if we had a million years. 105 | 106 | But do we know how to evaluate an arbitrary formula that comes from some theory? We can do it only if we have a definition of what formulas in that theory "mean", also known as a "semantics". 107 | 108 | So "SMT solving" is determining the satisfiability or unsatisfiability of formulas for some arbitrary theory or combination of theories that you plug in a semantics for, and an "SMT solver" is a computer program that does SMT solving. And, just as with SAT, the semantics for a theory on paper might be pretty simple, in the way that truth tables for propositional logic are simple, but the computer program can be a lot more complicated, in the way that CDCL and fancy heuristics for computerized solving of propositional logic formulas can be. In this course, we'll be trying to understand some of the complicated parts. 109 | 110 | ## Soundness and completeness; decidability 111 | 112 | We talked a little about soundness and completeness last time with regard to paradigms of SAT solving, and now we can generalize that to SMT solving, too. 113 | 114 | So, we're going to say that the "decision problem" for a given formula is determining whether or not it is valid. I'm following the book's definition here. But we could just as easily say that the decision problem is determining whether or not the formula is satisfiable, because they amount to the same problem. 115 | 116 | So then we can define "decision procedure": 117 | 118 | A "decision procedure for a theory $T$" is an algorithm that, given any formula of the theory $T$: 119 | - always terminates 120 | - when it returns 'Valid', the input formula is valid (**soundness:** the algorithm never lies and says the formula is valid when it is not) 121 | - when the input formula is valid, it returns 'Valid' (**completeness:** the algorithm never lies and says that the formula is *not* valid when it *is*) 122 | 123 | And we say that a theory is "decidable" if and only if there is a decision procedure for it. 124 | 125 | I think all the theories that we're going to talk about in this course are decidable theories. Once you know a theory is decidable, then the question becomes how hard the decision problem is for that theory. Most of the ones we're going to talk about have NP-complete decision problems. 126 | 127 | ## Normal forms 128 | 129 | It turns out that the notion of conjunctive normal form or CNF that we had from before also generalizes beyond propositional logic. Before, we just said that a clause was a disjunction of literals, and a formula was in CNF if it was a conjunction of clauses. All that still applies, except now a literal can be any atom or its negation. So a formula is in CNF if it's a conjunction of disjunctions of literals, regardless of what the atoms might be. 130 | 131 | There are some other useful normal forms to know about: 132 | 133 | - a formula is in disjunctive normal form (DNF) if it's a disjunction of conjunctions of literals. 134 | 135 | - a formula is in negation normal form (NNF) if negation is only allowed over atoms, and $\land$, $\lor$, and $\neg$ are the only allowed Boolean connectives. 136 | 137 | And the DNF and CNF formulas are both subsets of the NNF formulas. The book also covers an algorithm for converting formulas to CNF, which is kind of interesting to learn about, but we won't go over it now. 138 | 139 | 140 | -------------------------------------------------------------------------------- /lecture-notes/2019-10-02-introduction-to-decision-procedures-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/lecture-notes/2019-10-02-introduction-to-decision-procedures-1.pdf -------------------------------------------------------------------------------- /lecture-notes/2019-10-04-introduction-to-decision-procedures-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | documentclass: extarticle 4 | fontsize: 17pt 5 | mainfont: Helvetica 6 | mathfont: Helvetica 7 | --- 8 | 9 | \newcommand{\satisfies}{\vDash} 10 | \newcommand{\integers}{\mathbb{Z}} 11 | \newcommand{\naturalnumbers}{\mathbb{N}} 12 | 13 | # Lecture notes for: Introduction to decision procedures, part 2 14 | 15 | Lindsey Kuper 16 | 17 | October 4, 2019 18 | 19 | These are lecture notes to accompany sections 1.4-1.7 (pp. 14-23) of Kroening and Strichman's _Decision Procedures: An Algorithmic Point of View_, second edition. See for the full collection of notes. 20 | 21 | ## Agenda 22 | 23 | - First-order logic 24 | - What's a theory (formally)? 25 | - Plans for the rest of the quarter 26 | 27 | ## First-order logic 28 | 29 | **Q:** Questions left over from last time? 30 | 31 | So last time we talked about propositional logic, in which formulas just consist of Boolean variables, Boolean connectives ($\land$\, $\lor$, $\neg$), and parentheses. 32 | 33 | (By the way, as mentioned last time, "propositional calculus" is a synonym for "propositional logic", and there are other synonyms you could use. Maybe a logician or a philosopher or a historian of science would have more to say about what a calculus is versus what a logic is, but I'm a computer scientist, and to me "propositional calculus" and "propositional logic" mean exactly the same thing, and you should use whichever one you like better. I'm going to stick with "logic" because it's one fewer syllable.) 34 | 35 | So, we talked about propositional logic, and we talked informally about what a "theory" was, and we gave a couple of examples of theories. But today we're going to make precise what we mean by "theory", and to do that we're going to use the framework of first-order logic. 36 | 37 | (By the way, first-order logic is also called "predicate logic", or "predicate calculus", or "first-order predicate calculus". More synonyms.) 38 | 39 | First-order logic formulas consist of: 40 | 41 | - variables 42 | - **logical symbols**: 43 | - the standard Boolean connectives that we talked about before ($\land$\, $\lor$, $\neg$) 44 | - quantifiers ($\exists$ and $\forall$) --- these are new, but you shouldn't worry too much about them, because we're going to do away with them shortly 45 | - parentheses 46 | - **nonlogical symbols**: 47 | - function symbols 48 | - predicate symbols 49 | - constant symbols 50 | 51 | For instance, say we have an formula: $y = z \lor (\neg(x = z) \land x = 2)$. 52 | 53 | **Q:** So what are the nonlogical symbols in this formula? 54 | 55 | A: well, "=" is a nonlogical symbol. Which kind of nonlogical symbol is it? It's a binary predicate symbol. So it's a function that takes two arguments and returns true or false. When we write $y = z$, that can be thought of as syntactic sugar for $\mathit{equals}(y, z)$. 56 | 57 | And then "2" is a nonlogical symbol. Which kind of nonlogical symbol is 2? It's a constant. So there must be some domain of numbers that constants come from. 58 | 59 | So, we've been talking about how a formula is satisfiable if there exists an *assignment* of values to its variables that makes the formula evaluate to true. But in order to evaluate a formula that has nonlogical symbols, you need more than just an assignment; you also need to know what the nonlogical symbols in the formula mean. In other words, you need an **interpretation** of the nonlogical symbols. Furthermore, in order to come up with an assignment, you need to know the domain that your variables come from, because they might not just be Boolean variables. 60 | 61 | So, you really need three things in order to evaluate a formula: 62 | 63 | - a domain ($\naturalnumbers$ or $\integers$, for instance) 64 | - an interpretation of the nonlogical symbols in the formula 65 | - every function symbol maps to a function 66 | - every predicate symbol maps to a predicate 67 | - every constant symbol maps to a domain element 68 | - an assignment of a domain element to each (free) variable in the formula 69 | 70 | These three things together are what logicians call a **structure**. 71 | 72 | So now, with our logician hats on, we can refine our definition of "satisfiable". Up until now we've been saying that a formula is satisfiable if there's some assignment that makes it true. But now we can say this: 73 | 74 | - a formula is **satisfiable** if there exists a structure under which the formula is true. 75 | 76 | In some sources, you won't see the assignment being included as part of the structure --- they define a structure to just be a domain and an interpretation. In that case, you would say that a formula is satisfiable if there exists a structure and an assignment under which it's true. 77 | 78 | **Q:** Questions about this so far? 79 | 80 | A: So, I see one hitch in this so far, which is: maybe instead of asking if there's *any* structure that will make a formula true, what if you want to require that certain symbols mean certain things? For instance, in that formula that I wrote down earlier: 81 | 82 | $y = z \lor (\neg(x = z) \land x = 2)$ 83 | 84 | Presumably I picked this particular "2" symbol because I want it to mean the number two. And presumably I picked this particular "=" symbol because I want it to mean "equals", or some sort of equivalence relation. Sure, someone could come up with their own interpretation of the symbol "=" and the symbol "2" that would make this formula be true under lots of different assignments, but that's not helpful to me in the real world where I need to verify that my software works. So "is this formula with all these symbols in it satisfiable?" is actually not all that interesting of a question per se. The more interesting question is, is the formula satisfiable given the constraint that particular symbols have particular meanings? 85 | 86 | And this is where the idea of a theory comes in! Another way to ask the question that I just asked ("is the formula satisfiable given the constraint that particular symbols have particular meanings?") is, "is the formula satisfiable *in a given theory*?" 87 | 88 | ## What's a theory (formally)? 89 | 90 | So now that we have this concept of first-order logic and of structure, we can talk more precisely than we did yesterday about what it means to be a theory. In particular, a **theory** can be thought of as the particular first-order logic that you get when you specify: 91 | 92 | - a particular set of nonlogical symbols (which is called a **signature**), 93 | - a particular domain for variables and constants to come from, 94 | - a particular interpretation for the nonlogical symbols that you somehow specify 95 | 96 | So, for instance, maybe we define a theory as follows: 97 | 98 | - we put the "=" symbol in our signature 99 | - we pick a domain (say, the integers) 100 | - and, importantly, we specify an interpretation for "=" that makes it mean "equals" 101 | 102 | How do we do that? It turns out we can write down a set of axioms that constrain the interpretation of "=". In particular, there are three properties that are true of every equivalence relation. An equivalence relation has to be: 103 | 104 | - reflexive: $\forall x. x = x$ 105 | - symmetric: $\forall x, y. x = y$ 106 | - transitive: $\forall x, y, z. x = y \land y = z \implies x = z$ 107 | 108 | Specifying a set of axioms is not the only way to define a theory, but it's a common way. 109 | 110 | So now, finally, if we want to know if a formula is satisfiable *in a given theory*, we have to ask if there exists a structure that makes the formula true *and also* satisfies the axioms of the theory. 111 | 112 | If a formula is satisfiable in a theory $T$, we say that the formula is **$T$-satisfiable**. 113 | 114 | That is, we say that a formula is $T$-satisfiable for a given theory $T$ if there exists a structure that makes the formula true and also satisfies the axioms of $T$. 115 | 116 | Theories that are defined using this framework of first-order logic are called **first-order theories**. All the theories that we're going to be concerned with are first-order theories. 117 | 118 | **Q:** So, when we started using the framework of first-order logic, there's one thing that came along for the ride that, for the most part, we don't want. What is it? 119 | 120 | A: The quantifiers! The $\forall$ and $\exists$ quantifiers are part of the set of logical symbols that you can have in first-order logic, but for the most part, we don't want formulas that have these quantifiers in them. So, by moving to the framework of first-order logic, we gained the flexibility of being able to add our own new nonlogical symbols, but we also got more than we wanted, because we got the quantifiers too. 121 | 122 | Unfortunately, we can't do away with the quantifiers just by restricting things to a particular theory, because a theory only restricts the nonlogical symbols. So, if we want a particular first-order theory but we don't want the quantifiers that came along for the ride, we have to say that we want only the **quantifier-free fragment** of that theory. 123 | 124 | For the most part, we're going to be dealing with quantifier-free fragments of theories. For instance, last time we mentioned equality logic. It turns out that equality logic is just a name for the quantifier-free fragment of the theory that we just defined a minute ago. 125 | 126 | **Q:** Questions about anything so far? 127 | 128 | So, for everything we've just discussed, we've had our logician hats on, but for most of the rest of this course we're going to put our computer scientist hats back on. Which is to say, from now on, when we talk about theories, even though we *could* use the framework of first-order logic to talk about them, for the most part we're not going to, because for our purposes, doing that would be kind of awkward and pedantic and it wouldn't help us do what we actually want to do, which is to figure out how to design decision procedures for the theories that interest us --- or how to best make use of existing decision procedures for theories that interest us. (By "theories that interest us", I mean the ones that let us naturally encode properties that we want to prove.) 129 | 130 | ## Plans for the rest of the quarter 131 | 132 | Yay! You made it through week one! Only nine more to go! 133 | 134 | (look at course web page and discuss) 135 | 136 | -------------------------------------------------------------------------------- /lecture-notes/2019-10-04-introduction-to-decision-procedures-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/lecture-notes/2019-10-04-introduction-to-decision-procedures-2.pdf -------------------------------------------------------------------------------- /lecture-notes/2019-10-07-introduction-to-sat-solving-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | documentclass: extarticle 4 | fontsize: 17pt 5 | mainfont: Helvetica 6 | mathfont: Helvetica 7 | --- 8 | 9 | \newcommand{\satisfies}{\vDash} 10 | \newcommand{\integers}{\mathbb{Z}} 11 | \newcommand{\naturalnumbers}{\mathbb{N}} 12 | \newcommand{\true}{\mathrm{true}} 13 | \newcommand{\false}{\mathrm{false}} 14 | 15 | # Lecture notes for: Introduction to SAT solving, part 1 16 | 17 | Lindsey Kuper 18 | 19 | October 7, 2019 20 | 21 | These are lecture notes to accompany sections 2.1-2.2.3 (pp. 27-38) of Kroening and Strichman's _Decision Procedures: An Algorithmic Point of View_, second edition. See for the full collection of notes. 22 | 23 | ## Agenda 24 | 25 | - Motivating examples: probems encodable as SAT problems 26 | - Implementing SAT solvers 27 | - BCP recap 28 | - An elementary-school SAT solver (no guessing) 29 | 30 | ## Motivating examples: problems encodable as SAT problems 31 | 32 | **Q:** Questions left over from last time? 33 | 34 | There was one question last time that I want to try to address. So we talked about how we are for the most part only going to be interested in quantifier-free theories. 35 | 36 | And Will asked, "But you really need quantifiers to be able to talk about a lot of interesting things, don't you? Why can we get away without them?" 37 | 38 | I didn't have a great answer offhand. All I could think of is "Well, in this course we're interested in decision procedures that can actually run on a real computer, so we need our theories to be decidable, and for that I think we mostly need to avoid quantifiers. And the obvious success of SMT solving with quantifier-free theories demonstrates its usefulness." That answer is fine as far as it goes, but it didn't really answer the question. So: why *can* we do so much with quantifier-free theories? 39 | 40 | I guess one way to answer that question is to say, well, we know that just solving plain ol' SAT (without quantifiers allowed in the formulas) is NP-complete, therefore any NP problem can be encoded as a SAT problem, and so we already know that you don't actually need quantifiers to express (most?) computationally interesting problems. But your ability to exploit that fact depends on your ability to come up with a clever encoding in a quantifier-free theory. (And *that*, the machine can't do for you!) 41 | 42 | But there's yet another point to make, which is that when we ask a question of an SMT solver about a formula, the questions we're asking *do* implicitly contain quantifiers. If you're asking if the formula is satisfiable, then you're asking if there exists a satisfying assignment. And if you're asking if the formula is valid, the you're asking if, for all assignments, the formula is true. So there's an implicit quantification happening. 43 | 44 | So instead of thinking of most theories as "first-order logics minus the quantifiers", it might make sense to think of them as "first-order logics where you can quantify over assignments, and you have to do it around the outside of the whole formula". 45 | 46 | But enough about SMT; today we're going back to talking about SAT! And before we jump back into CDCL, maybe it'll be useful to start out by looking at a problem that can be encoded as SAT. 47 | 48 | So, say we're the FCC and we're assigning frequencies to radio stations. We have $n$ radio stations, $s_1, ... s_n$, and we have $k$ transmission frequencies, where $k < n$. So some stations need to share a frequency, but we want them to not be too close to each other. For now we're not going to consider _relative_ distance, and we're just going to say, okay, some pairs of stations are above a threshold for being too close, and other pairs are not. So we know all the pairs of stations that are too close. Say, maybe stations 3 and 4 are too close to each other to share a frequency. We have a set of all such pairs. 49 | 50 | By the way, the book chose to frame this problem as radio station frequency allocation, but the problem is very similar to the problem of register allocation in a compiler. Say you have to compile a program to run on some hardware. The program has some number of variables; the hardware has some number of registers, which might be fewer than the number of variables. So you need to figure out which variables conflict with each other. There's a notion of variables being "live" during some part of a program's run, and you need to first figure out which variables have overlapping live ranges. That's analogous to a pair of radio stations being too close. Then you need to make sure not to assign them to the same register. 51 | 52 | It's not quite the same problem, though, because in the case of the radio stations, if you don't have enough transmission frequencies, then the problem is just unsatisfiable. 53 | 54 | **Q:** But what does the compiler do if it doesn't have enough registers? 55 | 56 | A: It just allocates things in memory instead of in registers. So register allocation is really more of an optimization problem rather than a decision problem. If you don't have enough registers, your compiler usually isn't gonna be like, "Sorry! UNSAT!" 57 | 58 | **Q:** Actually, this is an interesting question. Under what conditions would you actually *want* the compiler to say "Sorry, UNSAT"? 59 | 60 | I think you might want that if you were compiling code to run on an embedded system that had some extremely limited amount of memory. 61 | 62 | I asked around about this on Twitter this morning, about whether there are compilers that ensure that compiled programs don't run out of memory at runtime, and I got a lot of interesting replies. I'll send a Canvas announcement pointing to the Twitter thread in case any of you want to peruse it. 63 | 64 | Anyway, it turns out that it's really straightforward to represent the input to this problem as a graph, and then the problem becomes how to color the graph. In the case of the radio stations, we say that every station is a node in the graph, and for every two stations that are too close together to share a frequency, we draw an edge between them. 65 | 66 | Likewise for the register allocation, we say that every variable is a node in the graph, and for every two variables that have overlapping live ranges, we draw an edge between them. 67 | 68 | Then the problem becomes to color the nodes, where the number of colors that we have is the number of slots that we have to allocate things into. So, frequencies in the case of radio stations, registers in the case of program variables. And the idea is to come up with a coloring so that adjacent nodes are assigned different colors. 69 | 70 | This is the graph colorability problem: does such a coloring exist? But we can also describe it as a SAT problem. 71 | 72 | The setup is: Define a set of Boolean variables $x_{ij}$ where $i$ ranges from 1 to $n$ and $j$ ranges from 1 to $k$. The idea is that variable $x_ij$ is set to true iff radio station $i$ is assigned the frequency $j$. 73 | 74 | **Q:** So, what constraints do we have that affect what our satisfying assignment can be? 75 | 76 | A: First, every station gets at least one frequency. So how do we encode that? 77 | 78 | Suppose there are 4 stations and 3 frequencies. Then the formula for expressing that each station gets at least one frequency would be: 79 | 80 | $(x_{11} \lor x_{12} \lor x_{13}) \land (x_{21} \lor x_{22} \lor x_{33}) \land (x_{31} \lor x_{32} \lor x_{33}) \land (x_{41} \lor x_{42} \lor x_{43})$ 81 | 82 | In general, for any number of $n$ stations and $k$ frequencies, the formula is a conjunction of clauses where each clause is the disjunction of $x_{i1}, ..., x_{ik}$. 83 | 84 | So that's making sure that every station gets at least one. 85 | 86 | Secondly, we have to make sure each station gets at _most_ one. This is a little bit harder to encode! 87 | 88 | But let's try to do it. Again, to make it concrete, let's still say there are 4 stations and 3 frequencies. 89 | 90 | The encoding of this one is kind of hairy. But, in general, if a station is assigned to a frequency you want to make sure that it isn't assigned to any other frequency. So if $x_{11}$ is true, then that means station 1 is assigned to frequency 1, so you then need to make sure that station 1 isn't assigned to frequencies 2 or 3. 91 | 92 | $((x_{11} \implies (\neg x_{12} \land \neg x_{13})) \land (x_{12} \implies \neg x_{13}))$ \ 93 | $\land$ \ 94 | $((x_{21} \implies (\neg x_{22} \land \neg x_{23})) \land (x_{22} \implies \neg x_{23}))$ \ 95 | $\land$ \ 96 | $((x_{31} \implies (\neg x_{32} \land \neg x_{33})) \land (x_{32} \implies \neg x_{33}))$ \ 97 | $\land$ \ 98 | $((x_{41} \implies (\neg x_{42} \land \neg x_{43})) \land (x_{42} \implies \neg x_{43}))$ 99 | 100 | Thirdly, you need the set of pairs of stations that are close to each other. So for every pair $(i, j)$ in that set, 101 | 102 | add an implication $x_{it} \implies \neg x_{jt}$ for every $t < k$. 103 | 104 | So, if stations 3 and 4 happen to be close, we have 105 | 106 | $(x_{31} \implies \neg x_{41}) \land (x_{32} \implies \neg x_{42}) \land (x_{33} \implies \neg x_{43})$ 107 | 108 | **Q:** Do you also need the other way around? That is, do you also need: 109 | 110 | $(x_{41} \implies \neg x_{31}) \land (x_{42} \implies \neg x_{32}) \land (x_{43} \implies \neg x_{33})$ 111 | 112 | A: It turns out you don't, because $p \implies q$ desugars to $q \lor \neg p$. So the above becomes: 113 | 114 | $(\neg x_{31} \lor \neg x_{41}) \land (\neg x_{32} \lor \neg x_{42}) \land (\neg x_{33} \lor \neg x_{43})$ 115 | 116 | So the SAT encoding of the problem consists of the conjunction of all these pieces. 117 | 118 | The book doesn't actually discuss how the solver operates on this particular problem; it merely gives it as an example of an encoding of a real-world problem as a SAT problem to help motivate the need for SAT solving. 119 | 120 | By the way, I thought it would be interesting to try to encode the problem of assigning papers to presenters in this class as a SAT problem (or maybe an SMT problem). But I didn't manage to come up with an encoding in the limited time I had to think about it, although I'm certain that it's possible. Might be something fun to try on your own if you want to get some practice encoding problems as SAT. 121 | 122 | ## Implementing SAT solvers 123 | 124 | **Q:** Questions about the example we just went over? 125 | 126 | OK, let's talk about implementing SAT solvers some more! 127 | 128 | We're going to assume from now on that the input to the solver is a Boolean formula in CNF. We can do this with no loss of generality because you can efficiently convert any SAT formula to CNF. We didn't go over it in class, but there's a standard algorithm for it called the Tseytin transformation. (Not Satan, as in the Prince of Darkness, but Tseytin.) The details of that conversion are in Chapter 1 of the book. 129 | 130 | So, given one of these CNF formulas, the goal of the solver is to find a satisfying assignment or determine that there is no satisfying assignment, and it does this by building up an assignment one variable at a time and then backtracking if it discovers it made a mistake. 131 | 132 | We're going to be talking about conflict-driven clause learning SAT solvers. As we talked about last Monday, you can think of there being three phases to the CDCL algorithm: 133 | 134 | - simplify: simplify the formula you have, update the current assignment with anything you can infer (BCP happens here) 135 | - decide: make a decision about a variable and its value, using some heuristic to choose which variable and which value to try next (we'll talk about heuristics laser) 136 | - learn: add a new clause to the formula summarizing information learned from a conflict, and backtrack to where you were before you made the decision that caused the conflict 137 | 138 | with the "simplify" and "decide" phases iterating until you encounter a conflict, in which case you go to the "learn" phase. 139 | 140 | So the book has a pictorial overview of the CDCL algorithm, and we can label parts of this figure with those three phases of simplify, decide, and learn. 141 | 142 | The "simplify" phase is BCP. The "decide" phase is "Decide", obviously. And the "learn" phase is the "AnalyzeConflict" and "Backtrack" 143 | 144 | ### BCP recap 145 | 146 | So, as CDCL solving proceeds, there are various states that a clause in a formula can be in: 147 | 148 | - **satisfied** if at least one of its literals is satisfied by the current partial assignment. (Recall that a clause is a disjunction.) 149 | - **conflicting** if all its literals are assigned and it is not satisfied by the current partial assignment. 150 | - **unit** if *all but one* of its literals are assigned and it is not satisfied. These are the ones that we said are hanging on the edge of being conflicting. 151 | 152 | It's the unit clauses that are particularly interesting, because they allow us to extend the assignment. In fact, they *require* us to extend the assignment! For instance, if we have the assignment $\{ x_1 = \true, x_2 = \false, x_4 = \true\}$, and we have the clause $(\neg x_1 \lor \neg x_4 \lor x_3)$, then we know we need to extend the assignment with $x_3 = \true$. 153 | 154 | This is called the **unit clause rule** -- whenever you have a unit clause, you must extend the current assignment with the binding that will satisfy that clause. 155 | 156 | Recall how the "Science of Brute Force" paper spoke of _unit clause propagation_, or UCP. That's what we're going to call Boolean constraint propagation, or BCP. But it's the same thing as that paper's UCP. And BCP is simply _repeated application of the unit clause rule_. 157 | 158 | **Q:** What's the name for a unit clause that _causes_ a particular literal to become assigned? 159 | 160 | A: We call it the **antecedent clause** of that literal. So in the example I just gave, $(\neg x_1 \lor \neg x_4 \lor x_3)$ is the antecedent clause of $x_3$. 161 | 162 | As CDCL runs, decisions get made about the values of variables, and we can think of these decisions as forming a binary tree. So for instance, if we decide the value of $x_1$ first, then that decision is made at depth 1 in the tree. Therefore the decision about $x_1 was made at **decision level** 1. Any other decisions that _have_ to get made as a result of that decision also happen at level 1. 163 | 164 | One important thing to keep in mind is that decisions are _guesses_, whereas when we add bindings to the assignment as a result of BCP, those aren't guesses. When you run CDCL, it might actually be the case that you don't have to make any guesses! Maybe you have a formula where it's already the case that you have a unit clause (because you had a unary clause in the formula, so you have a literal that you know has to be true). You don't want to make guesses unless it's necessary. 165 | 166 | So this suggests that you should also do BCP right away when you start CDCL, even before you make any decisions! And, indeed, that's what this picture looks like. 167 | 168 | ### An elementary-school SAT solver (no guessing) 169 | 170 | When I was a kid in elementary school, from time to time we had to do these logic puzzles that would be something along the lines of, there are five people, and they all have favorite colors, and they all have favorite sports, and they all have favorite animals, and your job would be to fill in some table assigning people to their favorite colors or sports or animals or what have you. And you'd get a list of constraints, which would be something like "the person whose favorite sport is basketball hates the color red", and "the person whose favorite animal is the zebra plays either soccer or volleyball" and so on. And one of these constraints would give you a place to start from that would allow you to propagate information to further constrain the search. 171 | 172 | As I recall, these puzzles were always designed in such a way that you would never have to make guesses and then backtrack if your guess was wrong. You would instead be able to figure out the entire assignment by propagating what you already knew. In other words, all decisions would be made at decision level 0, in the initial BCP phase. 173 | 174 | By the way, those logic puzzles were usually always designed in such a way that they *had* a solution. But it is possible that during this initial BCP phase, you find out that the formula does in fact not have a solution. So, if you implemented the elementary school logic puzzle version of a SAT solver, it would look like this: 175 | 176 | \begin{verbatim} 177 | // Elementary-school SAT solver 178 | // given a formula F, returns SAT or UNSAT 179 | CDCL(F): 180 | // initialize empty assignment 181 | A = {} 182 | // do BCP on the initial formula 183 | if BCP(F, A) = conflict 184 | return UNSAT 185 | while notAllVariablesAssigned(F, A) 186 | // Give up and complain to the 187 | // teacher that the problem is underconstrained 188 | return SAT 189 | \end{verbatim} 190 | 191 | Of course, we're not doing the elementary school logic puzzle version of CDCL, we're doing the version of CDCL that actually has to deal with having to make guesses. What the CDCL algorithm gives you is a framework for making good guesses and then gracefully backing out of our guesses when it turns out we made bad ones. 192 | 193 | So, something is going to have to go here in place of "give up and complain to the teacher", right? 194 | 195 | \begin{verbatim} 196 | // given a formula F, returns SAT or UNSAT 197 | CDCL(F): 198 | // initialize empty assignment 199 | A = {} 200 | // do BCP on the initial formula 201 | if BCP(F, A) = conflict 202 | return UNSAT 203 | while notAllVariablesAssigned(F, A) 204 | // Do stuff 205 | return SAT 206 | \end{verbatim} 207 | 208 | Next time, we'll talk about what we have to do in place of "Do stuff" there. 209 | -------------------------------------------------------------------------------- /lecture-notes/2019-10-07-introduction-to-sat-solving-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/lecture-notes/2019-10-07-introduction-to-sat-solving-1.pdf -------------------------------------------------------------------------------- /lecture-notes/2019-10-09-introduction-to-sat-solving-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | documentclass: extarticle 4 | fontsize: 17pt 5 | mainfont: Helvetica 6 | mathfont: Helvetica 7 | --- 8 | 9 | \newcommand{\satisfies}{\vDash} 10 | \newcommand{\integers}{\mathbb{Z}} 11 | \newcommand{\naturalnumbers}{\mathbb{N}} 12 | \newcommand{\true}{\mathrm{true}} 13 | \newcommand{\false}{\mathrm{false}} 14 | 15 | # Lecture notes for: Introduction to SAT solving, part 2 16 | 17 | Lindsey Kuper 18 | 19 | October 9, 2019 20 | 21 | These are lecture notes to accompany sections 2.2.4-2.2.9 (pp. 38-50) of Kroening and Strichman's _Decision Procedures: An Algorithmic Point of View_, second edition. See for the full collection of notes. 22 | 23 | ## Agenda 24 | 25 | - Recap of last time 26 | - Grown-up SAT solving: the full CDCL algorithm 27 | - Making decisions 28 | - Learning from our bad decisions 29 | - Knowing when to give up, and when to back up and try again 30 | - Implication graphs 31 | 32 | ## Recap of last time 33 | 34 | OK! So when we finished last time, we wrote down what I called an "elementary school" SAT solving algorithm. It looked like this: 35 | 36 | \begin{verbatim} 37 | // Elementary-school SAT solver 38 | // given a formula F, returns SAT or UNSAT 39 | CDCL(F): 40 | // initialize empty assignment 41 | A = {} 42 | // do BCP on the initial formula 43 | if BCP(F, A) = conflict 44 | return UNSAT 45 | while notAllVariablesAssigned(F, A) 46 | // Give up and complain 47 | return SAT 48 | \end{verbatim} 49 | 50 | So the idea is that, when we were solving one of those logic puzzles from elementary school, we could generally solve them without making any guesses. In other words, we never had to use the "Decide" part of the CDCL algorithm, which is the part that makes guesses. We just considered what we currently knew, and then propagated that knowledge to extend the assignment until all variables were assigned. 51 | 52 | As we've discussed, BCP is just _repeated application of the unit clause rule_. Recall that the unit clause rule says that whenever you have a unit clause, you must extend the current assignment with the binding that will satisfy that clause. So in this algorithm, you do BCP and keep on extending the assignment until you either come up with a conflicting clause, in which case the formula is unsatisfiable, or until you run out of unassigned variables, in which case you're done and the formula is satisfiable. If neither of those things happen, then you give up and complain to the teacher, "This problem is too hard!" 53 | 54 | ## Grown-up SAT solving: the full CDCL algorithm 55 | 56 | If we happen to have a formula that *can* be solved by just propagating what we know until every variable is assigned or until we come up with a conflicting clause, then the elementary school SAT solver is good enough. It would have been good enough for those elementary school puzzles, because those puzzles could be solved without guessing. But, more generally, we're going to want to solve formulas that may require some amount of guessing. So we want to do something here instead of "give up and complain". 57 | 58 | ### Making decisions 59 | 60 | Being a grown-up sometimes requires making decisions even when you don't have all the information, and so grown-up SAT solving will have to do that too. 61 | 62 | **Q:** So, what do we have to do instead of give up and complain? Any suggestions? 63 | 64 | A: Well, we're going to have to make a guess, right? We're going to have to pick a variable and say "suppose this one is true", or "suppose this one is false". And we'll have to keep track of the place where we made a decision and everything that followed from it, in case it comes to pass that we have to undo the decision later. 65 | 66 | So now we need to use the concept of "decision level" that we introduced last time. 67 | 68 | In the elementary-school SAT solver, we never actually had to make a guess. All variables were assigned at decision level 0. In other words, we didn't have any _decision variables_, which are variables that get their assignment as a result of a guess. But now we're going to have to start making decisions, and keeping track of where we made them. That's what the decision level is for. So we'll introduce a variable called `decisionLevel` for that. 69 | 70 | And now, instead of giving up and complaining, we need to venture bravely into the unknown and make a decision about some variable in the formula. So, we're going to pick out an as-yet-unassigned variable, and we're going to extend the assignment with a binding for it. This will be our first decision variable. 71 | 72 | How do we know which variable to assign to and whether to assign it true or false? We don't. We make the choice using some heuristic. The choice of heuristic is orthogonal to the CDCL algorithm, although of course it has profound implications for the performance of the solver, and different heuristics are more appropriate for different kinds of formulas. We don't have time to get into decision heuristics now, though. 73 | 74 | \begin{verbatim} 75 | // given a formula F, returns SAT or UNSAT 76 | CDCL(F): 77 | // initialize empty assignment 78 | A = {}, decisionLevel = 0 79 | // do BCP on the initial formula 80 | if BCP(F, A) = conflict 81 | then return UNSAT 82 | while notAllVariablesAssigned(F, A) 83 | decisionLevel++ 84 | // add a new decision to the assignment 85 | // based on some heuristic 86 | A = A extended with DECIDE(F, A) 87 | // Do stuff (more to come here...) 88 | return SAT 89 | \end{verbatim} 90 | 91 | Every time we make a decision, we increment the decision level. You can visualize this as a binary tree: if we first decide $x_1$, then that decision is made at decision level 1, and the next decision will be made at decision level 2, and so on. The decision level of a variable is the depth of the binary tree at which that variable was assigned. 92 | 93 | Of course, we don't have to make a decision about every variable. For many variables, their value will be implied by BCP. We call these _implied variables_, as opposed to decision variables. 94 | 95 | The decision level of an implied variable is the maximum of the decision levels of the other variables in its _antecedent clause_. (Recall that the antecedent clause of a variable is the unit clause that implied its value. Decision variables don't have antecedent clauses; implied variables do.) 96 | 97 | And whenever we update an assignment with a new variable, either by doing BCP or by calling DECIDE, we keep track of the decision level of that variable, too. 98 | 99 | ### Learning from our bad decisions 100 | 101 | Once we've made a decision about a variable, there are two possibilities. Either it was a bad decision, meaning it will lead to a conflict, or it was a good decision, meaning it will lead to the formula being satisfied. 102 | 103 | **Q:** How do we find out whether our decision leads to a conflict? 104 | 105 | A: We can do BCP again! We've extended our assignment, right? So maybe that extended assignment will lead to a conflict, and we run BCP to find out. 106 | 107 | **Q:** What do we do if BCP tells us that we have a conflict? 108 | 109 | A: Well, up above, when we encountered a conflict, we just returned UNSAT right away, because we knew then that the formula was unsatisfiable. But now, we can't do that, because the conflict we encountered might not be because the formula is unsatisfiable; it might have merely been the result of us making a bad decision! 110 | 111 | **Q:** How do we know which kind of conflict we have on our hands? 112 | 113 | A: We can _analyze_ the conflict! We do that by...calling ANALYZE-CONFLICT, of course. 114 | 115 | \begin{verbatim} 116 | // given a formula F, returns SAT or UNSAT 117 | CDCL(F): 118 | //initialize empty assignment 119 | A = {}, decisionLevel = 0 120 | // do BCP on the initial formula 121 | if BCP(F, A) = conflict 122 | return UNSAT 123 | while notAllVariablesAssigned(F, A) 124 | decisionLevel++ 125 | // add a new decision to the assignment 126 | // based on some heuristic 127 | A = A extended with DECIDE(F, A) 128 | if BCP(F, A) = conflict 129 | // ANALYZE-CONFLICT returns a backtracking 130 | // level and a new conflict clause 131 | (bl, C) = ANALYZE-CONFLICT() 132 | // add newly learned conflict clause to F 133 | F = F extended with C 134 | // Do stuff (more to come here...) 135 | return SAT 136 | \end{verbatim} 137 | 138 | ANALYZE-CONFLICT looks at the current conflicting clause in the formula and tells us two things: a _backtracking level_, which is the decision level that we need to go back to in order to undo our mistake, and a _conflict clause_, which is the _newly learned clause_ that we need to add to our formula. 139 | 140 | Let's talk about the conflict clause first. By the way, there's almost a naming collision here, between "conflict clause" and "conflicting clause". These are not the same thing! 141 | 142 | **Q:** What's a conflicting clause? We talked about this last time. 143 | 144 | A: A clause is conflicting if all its literals are assigned and it is not satisfied by the current partial assignment. It's a state that a clause can be in during the process of SAT solving, depending on what the current partial assignment is. So, the process of BCP can result in a clause becoming conflicting. 145 | 146 | On the other hand, a _conflict clause_, which we first talked about way back for the first reading assignment, is a newly learned clause that you add to the original formula during solving. A conflict clause can be thought of as summarizing information that was already in the formula. The purpose of adding a conflict clause to a formula is to help us solve the formula faster by avoiding assignments that won't work out. A conflict clause is produced as a _result_ of a conflict that arises during the process of BCP, but a conflict clause is not the same thing as a conflicting clause! This is a really unfortunate almost-collision of terminology. 147 | 148 | By the way, in real CDCL implementations, instead of just tacking the conflict clause onto the end of the formula, we would have a _clause database_ that we would add the new clause to. We would probably also have some sort of fancy efficient data structure for representing the formula. We could spend weeks on this topic alone if we had time. 149 | 150 | OK, so that's the conflict clause, but ANALYZE-CONFLICT also returned something else: a backtracking level. The backtracking level is the decision level that we need to go back to in order to undo our mistake. Essentially, it's a number that tells you how far in the decision tree you need to back up. 151 | 152 | The backtracking level tells us something important about the conflict we encountered: whether it was because the formula is actually unsatisfiable, or merely the result of making a bad decision. If ANALYZE-CONFLICT returns, say, decision level 2, then we need to undo any decisions made at higher levels (and any assignments that happened as a result of those decisions), and try again. If ANALYZE-CONFLICT returns decision level 0, that means we need to go back to the very first decision made. 153 | 154 | ### Knowing when to give up, and when to back up and try again 155 | 156 | **Q:** What if ANALYZE-CONFLICT returns -1 as the backtracking level? 157 | 158 | A: Then it's telling us to back up further than it's possible to back up. In other words, a backtracking level of -1 means that the conflicts we're encountering aren't the fault of our bad decisions --- it's just that the formula is unsatisfiable! So, if _bl_ is less than 0, we just return UNSAT. 159 | 160 | Otherwise, if the backtracking level is 0 or higher, it means that we have a place to back up to, and we need to undo the decision that led to the conflict. To do this, we call BACKTRACK with the backtracking level and the current assignment A. BACKTRACK updates the assignment to _remove_ any bindings that it added as a result of the bad decision that we want to undo. (How does it know which ones those were? Because we've been recording the decision level of every assigned variable.) 161 | 162 | Finally, we update the current decision level to whatever that new backtracking level is, and we go back up to the top of the "while notALlVariablesAssigned(F, A)" loop and keep going from the point that we backtracked to. The process continues until we either return UNSAT, or we assign every variable and BCP doesn't discover any conflicts, in which case we fall out the bottom of the while loop and return SAT. And now we've finally written down the whole CDCL algorithm! 163 | 164 | \newpage 165 | 166 | \begin{verbatim} 167 | // given a formula F, returns SAT or UNSAT 168 | CDCL(F): 169 | //initialize empty assignment 170 | A = {}, decisionLevel = 0 171 | // do BCP on the initial formula 172 | if BCP(F, A) = conflict 173 | return UNSAT 174 | while notAllVariablesAssigned(F, A) 175 | decisionLevel++ 176 | // add a new decision to the assignment 177 | // based on some heuristic 178 | A = A extended with DECIDE(F, A) 179 | if BCP(F, A) = conflict 180 | // ANALYZE-CONFLICT returns a backtracking 181 | // level and a new conflict clause 182 | (bl, C) = ANALYZE-CONFLICT() 183 | // add conflict clause to formula 184 | F = F extended with C 185 | // if the backtracking level returned by 186 | // ANALYZE-CONFLICT was less than 1, 187 | // we know the formula is unsatisfiable 188 | if bl < 0 189 | return UNSAT 190 | else 191 | // undo our mistake; go back to the last 192 | // decision level before the mistake 193 | BACKTRACK(A, bl) 194 | decisionLevel = bl 195 | return SAT 196 | \end{verbatim} 197 | 198 | \newpage 199 | 200 | By the way, this way of expressing the algorithm is a bit different what Kroening and Strichman show in chapter 2 (although it amounts to the same thing). It is closer to what appears in chapter 4 of the _Handbook of Satisfiability_. It's also a lot like the version that Emina Torlak uses in [her slides](https://courses.cs.washington.edu/courses/cse507/19au/doc/L04.pdf). (In particular, as in Emina's slides, I explicitly show extending the formula with the learned conflict clause as part of the main CDCL algorithm, instead of making that a part of ANALYZE-CONFLICT.) 201 | 202 | During solving, the decision level may move up and down. It gets incremented every time we make a new decision, but it may jump backward by one or more based on what ANALYZE-CONFLICT returns. 203 | 204 | We've seen the overall structure of the algorithm, but we glossed over how DECIDE works and how ANALYZE-CONFLICT works. We don't have time to talk about either of these now, but we'll introduce the concept of an _implication graph_, which helps us understand how ANALYZE-CONFLICT can construct conflict clauses. 205 | 206 | ## Implication graphs 207 | 208 | Suppose we have the following formula: 209 | 210 | $(x_1 \lor \neg x_4) \land (x_1 \lor x_3) \land (\neg x_3 \lor x_2 \lor x_4)$ 211 | 212 | When solving this formula with CDCL, we start by trying to do BCP, but there are no unit clauses. So we go on to picking a variable to decide. Suppose we pick $x_4$ and assign it $\false$. 213 | 214 | We write "$\neg x_4@1$" to denote that $x_4$ was assigned $\false$ at decision level 1. 215 | 216 | **Q:** Now we can do BCP again. Does this result in any new implied variables? 217 | 218 | A: No. So we need to decide another variable. Suppose we pick $x_1$ and assign it $\false$ as well. So we have $\neg x_1@2$. 219 | 220 | **Q:** And now we do BCP yet again. Any new implied variables this time? 221 | 222 | A: Yes! This time we have $x_3@2$ and $x_2@2$ (denoting that $x_3$ and $x_2$, respectively, were assigned $\true$ at decision level 2). Notice that the decision level for both of these is the maximum decision level of the other variables in their antecedent clauses. The antecedent clause for $x_3$ was $(x_1 \lor x_3)$, and the antecedent clause for $x_2$ was $(\neg x_3 \lor x_2 \lor x_4)$. 223 | 224 | There are no more unassigned variables, so we've determined that the formula is satisfiable. (That was an easy one --- we didn't have any conflicts.) 225 | 226 | We can use the notion of antecedent clauses to define a directed acyclic graph that connects assigned variables to one another. Every assigned variable is a node in the graph. The edges in the graph come from antecedent clauses: for each variable $x$, there is an edge from each variable in $x$'s antecedent clause to $x$. ($x$ also occurs in its own antecedent clause, but we omit the edge from $x$ to itself.) 227 | 228 | Only implied variables have antecedent clauses, so only implied variables can have incoming edges. Decision variables have no antecedent clauses, so they cannot have incoming edges, only outgoing edges. That is, they are _source_ nodes in the graph. 229 | 230 | This graph is called the **implication graph**. The convention when drawing these implication graphs is to start with decision variables the left and have directed edges go to the right. 231 | 232 | For example, an implication graph for the series of assignments we just did would be as follows: on the left we have two decision variables, $\neg x_4@1$ and $\neg x_1@2$. There's no edge between these two; they've both decision variables, so neither has any incoming edges. 233 | 234 | Then from BCP we get $x_3@2$. Its antecedent was $(x_1 \lor x_3)$, so we add an edge from $x_1$ to $x_3$. And we also have $x_2@2$. Its antecedent was $(\neg x_3 \lor x_2 \lor x_4)$, so it has incoming edges from both $x_3$ and $x_4$. 235 | 236 | The implication graph looks like this: 237 | 238 | \begin{verbatim} 239 | 240 | ~x_4@1 ------------- \ 241 | \ 242 | > 243 | x2@2 244 | > 245 | / 246 | ~x_1@2 ------> x_3@2 / 247 | 248 | \end{verbatim} 249 | 250 | If unit propagation results in a clause being conflicting, then we add a special node called a conflict node to the implication graph, and we add edges from the nodes representing the variables of the conflicting clause to the conflict node. The conflict node is always a _sink_ node in the graph. 251 | 252 | For instance, suppose that our formula is the following: 253 | 254 | $(x_1 \lor \neg x_2) \land (x_1 \lor \neg x_3) \land (x_2 \lor x_3) \land \cdots$ 255 | 256 | Suppose we begin by assigning $\neg x_1@0$. Then from BCP we get $\neg x_2@0$ and $\neg x_3@0$, making the third clause in the formula conflicting. 257 | 258 | The implication graph looks like this: 259 | 260 | \newpage 261 | 262 | \begin{verbatim} 263 | ~x_2@0 264 | > \ 265 | / \ 266 | / > 267 | ~x_1@0 conflict 268 | \ > 269 | \ / 270 | > / 271 | ~x_3@0 272 | \end{verbatim} 273 | 274 | For implication graphs that have a conflict node, the source nodes that the conflict node can be reached from represent the decision variables that played a role in the conflict. So, one way to construct a conflict clause is to take the _disjunction of the negation_ of those assignments. For example, for the above simple formula, the conflict clause is the unary clause $(x_1)$, because the source node in the implication graph set $x_1$ to $\false$. 275 | 276 | Does the unary clause $(x_1)$ tell us anything that the original formula didn't? No. But that's the point: conflict clauses don't add new information, they just summarize existing information. Had the clause $(x_1)$ been a part of the formula from the beginning, we never would have tried assigning $x_1 = \false$ because we would have been forced to assign $x_1 = \true$ during the initial BCP. By adding the conflict clause, we avoid exploring any other assignments that set $x_1 = \false$. 277 | 278 | There are more sophisticated ways of constructing conflict clauses, but it works pretty well to just look at the implication graph, find all the literals associated with source nodes from which the conflict node can be reached, and then take the disjunction of their negations! 279 | -------------------------------------------------------------------------------- /lecture-notes/2019-10-09-introduction-to-sat-solving-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/lecture-notes/2019-10-09-introduction-to-sat-solving-2.pdf -------------------------------------------------------------------------------- /lecture-notes/2019-10-11-introduction-to-smt-solving.md: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | documentclass: extarticle 4 | fontsize: 17pt 5 | mainfont: Helvetica 6 | mathfont: Helvetica 7 | --- 8 | 9 | \newcommand{\satisfies}{\vDash} 10 | \newcommand{\integers}{\mathbb{Z}} 11 | \newcommand{\naturalnumbers}{\mathbb{N}} 12 | \newcommand{\true}{\mathrm{true}} 13 | \newcommand{\false}{\mathrm{false}} 14 | 15 | # Lecture notes for: Introduction to SMT solving 16 | 17 | Lindsey Kuper 18 | 19 | October 11, 2019 20 | 21 | These are lecture notes to accompany sections 3.1-3.4 (pp. 59-72) of Kroening and Strichman's _Decision Procedures: An Algorithmic Point of View_, second edition. See for the full collection of notes. 22 | 23 | ## Agenda 24 | 25 | - Eager and lazy solvers 26 | - The DPLL($T$) framework 27 | - Boolean abstractions and overapproximations of satisfiability 28 | - The role of the theory solver 29 | - Offline and online solving 30 | 31 | ## Eager and lazy solvers 32 | 33 | We've been discussing the architecture of CDCL SAT solvers. Now we're going to talk about how we can solve formulas written using more interesting theories. In particular, we want to look at solvers for quantifier-free fragments of first-order theories, as we talked about a few lectures ago. Instead of a plain old SAT formula, we might have, say, a linear real arithmetic formula, such as, for instance, 34 | 35 | $((x_1 > 1) \land (2x_1 < 5)) \lor \neg(x_2 = 0)$. 36 | 37 | So, our formulas still have _propositional structure_, but the atoms of the formulas depend on the theory we're using. 38 | 39 | There are traditionally two approaches to SMT solving: the **eager** approach and the **lazy** approach. Eager SMT solving involves compiling the entire SMT formula to a plain old SAT formula and then solving the SAT formula with a SAT solver. This is possible to do for any decidable theory, and is similar in spirit to to compiling a program in a high-level language to assembly language. But the formula can grow in size exponentially when it is encoded as SAT, and moreover, the eager approach means we lose the opportunity to reason at the (higher) level of the theory we're using, instead of at the (lower) level of SAT formulas. 40 | 41 | That said, there are some state-of-the-art eager SMT solvers. One of them, for instance, is the _STP_ solver, which is what the first paper on our reading list is about. STP solves formulas in the theory of bit-vectors and arrays by eagerly compiling them to SAT (after some preprocessing). 42 | 43 | Most modern SMT solvers, though, are _lazy_. In the lazy approach, a SAT solver is still involved, but we also have specialized _theory solvers_ that interact with the underlying SAT solver during the solving process. That is, the solving process is an interplay between the SAT solver and the theory solver. 44 | 45 | An SMT solver like Z3 has multiple built-in theory solvers, each for a specific theory, although for a given problem you might only use one of the built-in theories. 46 | 47 | Today we're going to restrict our attention to discussing lazy SMT solvers, which are the topic of chapter 3 of Kroening and Strichman. It's a sign of how much lazy SMT solving has become the norm in the last ten years that the second edition of Kroening and Strichman, which came out in 2016, made chapter 3 only about lazy solving. There used to be stuff about eager solving in chapter 3 in the first edition of the book, which came out in 2008, but in the new edition they demoted it to chapter 11. (So if you want to read about eager solvers, look at chapter 11 of the book.) 48 | 49 | ## The DPLL(T) framework 50 | 51 | The lazy SMT solver framework we'll discuss is commonly known as DPLL($T$). The "($T$)" part is to indicate that it is parameterized by some theory $T$. That is, you can plug in a theory solver for your theory of choice into the DPLL($T$) framework, and that theory solver will interact with the underlying SAT solver, which, generally speaking, is a CDCL SAT solver. (As I've mentioned, DPLL is the predecessor to CDCL, and doesn't involve clause learning.) So DPLL($T$) is a misnomer; it should really be called CDCL($T$), but the name DPLL($T$) seems to have stuck. 52 | 53 | In the DPLL($T$) framework, the underlying CDCL SAT solver and the theory solver for the theory $T$ have distinct roles to play. 54 | 55 | What does the theory solver have to be able to do? The theory solver that you plug in to the DPLL($T$) framework needs to be able to handle _conjunctions of literals_ from the theory $T$. (Recall that a literal is either an atom or its negation.) 56 | 57 | Now, building a theory solver that can handle conjunctions of literals for a given theory is not necessarily easy to do. In fact, the design and implementation of these theory solvers is the topic of most of the rest of the Kroening and Strichman book after this chapter! 58 | 59 | But let's assume for a moment that we do have such a theory solver for a particular theory. That is, we have a solver that can take a formula that consists of a conjunction of literals from $T$ and tell us either "satisfiable" or "unsatisfiable". 60 | 61 | And we'll follow Kroening and Strichman and pick a really simple theory to start with, which is the theory of equality. 62 | 63 | ### Boolean abstractions and overapproximations of satisfiability 64 | 65 | To do lazy SMT solving, we need a **Boolean abstraction** of the original formula. These are also known as **propositional skeletons**, and that's what the book calls them. But I'll just say "Boolean abstraction" because it's shorter. 66 | 67 | To get the Boolean abstraction, or propositional skeleton if you like, we take each atom of the linear arithmetic formula and replace it with a new Boolean variable. Recall that atoms are formulas with no propositional structure. 68 | 69 | For instance, in our linear real arithmetic formula $((x_1 > 1) \land (2x_1 < 5)) \lor \neg(x_2 = 0)$, the atoms are $(x_1 > 1)$, $(2x_1 < 5)$, and $(x_2 = 0)$. 70 | 71 | So the Boolean abstraction of that formula is $(b_1 \land b_2) \lor \neg b_3$ (I'm using $b$ to make it more obvious that the variables are Booleans). 72 | 73 | Notice that the Boolean abstraction has three variables (which are Boolean variables) whereas the original formula had two (which are real numbers). So in general, the number of variables doesn't stay the same from the original formula to the Boolean abstraction. 74 | 75 | The function that turns a formula into its Boolean abstraction is called, unsurprisingly, a **Boolean abstraction function**. 76 | 77 | For our running example, we're using the theory of equality. In this theory, atoms are equalities, like $x = y$. So here's a formula in the theory of equality: 78 | 79 | $x = y \land ((y = z \land \neg(x = z)) \lor x = z)$ 80 | 81 | And its Boolean abstraction looks like this: 82 | 83 | $b_1 \land ((b_2 \land \neg b_3) \lor b_3)$ 84 | 85 | Since the Boolean abstraction is just a SAT formula, we can pass it to a SAT solver, which will run and come up with an assignment. 86 | 87 | **Q:** Is the Boolean abstraction satisfiable? 88 | 89 | A: Sure, of course it is. There are multiple satisfying assignments, even. But let's suppose the SAT solver happens to produce the following satisfying assignment: 90 | 91 | $\{b_1 = \true, b_2 = \true, b_3 = \false\}$ 92 | 93 | But that's a satisfying assignment for the Boolean abstraction, not for the original formula. 94 | 95 | **Q:** If the Boolean abstraction was satisfiable, does that mean that the original formula is satisfiable? 96 | 97 | A: No, not necessarily! So we still have to determine whether the original formula is satisfiable. We'll come back to that. 98 | 99 | But let's say we had a different equality logic formula to begin with. Say we had this. 100 | 101 | $(x = y \lor x = z) \land \neg(x = y) \land (x = y \lor \neg(x = z))$ 102 | 103 | Then the Boolean abstraction would be this: 104 | 105 | $(b_1 \lor b_2) \land \neg b_1 \land (b_1 \lor \neg b_2)$ 106 | 107 | **Q:** Is this one satisfiable? 108 | 109 | A: No, this one is unsatisfiable. 110 | 111 | **Q:** Does that mean that the original formula was unsatisfiable? 112 | 113 | A: It turns out that the answer is yes! In general, _if the Boolean abstraction of a formula is unsatisfiable, then so is the original formula_. However, if the Boolean abstraction is satisfiable, then the original formula _may or may not_ be satisfiable. 114 | 115 | - Boolean abstraction is unsatisfiable $\implies$ original formula is unsatisfiable modulo the theory, and we're done, yay! 116 | - Boolean abstraction is satisfiable $\implies$ original formula may or may not be satisfiable modulo the theory, and we have more work to do. 117 | 118 | We say that the Boolean abstraction **overapproximates** the satisfiability of the original formula. 119 | 120 | That "more work to do" part is where the theory solver comes in. 121 | 122 | ### The role of the theory solver 123 | 124 | OK, so suppose we have a Boolean abstraction that _is_ satisfiable. Then what? 125 | 126 | Well, now begins a conversation between the SAT solver and the theory solver. 127 | 128 | Going back to our original formula $x = y \land ((y = z \land \neg(x = z)) \lor x = z)$, the SAT solver determined that its Boolean abstraction $b_1 \land ((b_2 \land \neg b_3) \lor b_3)$ is satisfiable with the assignment $\{b_1 = \true, b_2 = \true, b_3 = \false\}$. 129 | 130 | But we still need to figure out whether the original formula is satisfiable. 131 | 132 | Now what we can do is go back to the theory solver. Recall that the theory solver can only solve conjunctive formulas in the theory. But we can construct one of those by just writing down the formula that corresponds to the assignment that the SAT solver just gave us! 133 | 134 | In particular, the SAT solver gave us this assignment: $\{b_1 = \true, b_2 = \true, b_3 = \false\}$. $b_1$ corresponds to the atom $x = y$, $b_2$ to the atom $y = z$, and $b_3$ to the atom $x = z$. So, we can write down the following formula: 135 | 136 | $x = y \land y = z \land \neg(x = z)$ 137 | 138 | We hand that to the theory solver (recall we're assuming we have one of those). And the theory solver runs, and what do you know? It returns "unsatisfiable". 139 | 140 | So now what? Well, what happens now is similar in spirit to what happened in CDCL, when we ran into a conflict using a particular partial assignment and then we had to learn a clause that would prevent us from trying that partial assignment again. 141 | 142 | So, what we want to do is try again with the SAT solver and get it to come up with a _different_ assignment that _also_ satisfies the Boolean abstraction, and that moreover corresponds to a satisfiable formula in the theory. So what we can do is take the _negation_ of the unsatisfiable formula above: 143 | 144 | $\neg(x = y \land y = z \land \neg(x = z))$ 145 | 146 | Because this is a negation of an unsatisfiable formula, that means it's always true. We convert that back into a Boolean abstraction: 147 | 148 | $\neg(b_1 \land b_2 \land \neg(b_3))$ 149 | 150 | which is the equivalent of: 151 | 152 | $\neg b_1 \lor \neg b_2 \lor b_3$ 153 | 154 | So that's a clause that we can add to our Boolean abstraction: 155 | 156 | $b_1 \land ((b_2 \land \neg b_3) \lor b_3) \land (\neg b_1 \lor \neg b_2 \lor b_3)$ 157 | 158 | This newly added clause is called a **blocking clause**. The purpose of the blocking clause is to prevent the SAT solver from coming up with the same assignment that it came up with last time. 159 | 160 | The blocking clause is analogous to the conflict clauses that the SAT solver learns during CDCL. In fact, some sources call it a "theory conflict clause". Kroening and Strichman call it a blocking clause. Either name works. 161 | 162 | And now we go back to the SAT solver once again. 163 | 164 | The SAT solver runs, and it comes up with another satisfying assignment: 165 | 166 | $\{b_1 = \true, b_2 = \true, b_3 = \true\}$. 167 | 168 | And this new satisfying assignment from the SAT solver corresponds to the following formula in the theory: 169 | 170 | $x = y \land y = z \land x = z$ 171 | 172 | So we run _that_ through the theory solver, and the theory solver reports that it is satisfiable. 173 | 174 | And this means that the original formula in the theory, which was 175 | 176 | $x = y \land ((y = z \land \neg(x = z)) \lor x = z)$, 177 | 178 | is indeed satisfiable. 179 | 180 | To sum up, this is the overall pattern: 181 | 182 | - Given a formula in the theory, construct a Boolean abstraction of it that _overapproximates_ satisfiability. 183 | - If the SAT solver returns "unsatisfiable", we're done, yay. 184 | - If the SAT solver returns "satisfiable", check to make sure that the satisfying assignment is legitimate, as follows: 185 | - Run the theory solver on the formula corresponding to the assignment returned by the SAT solver. 186 | - If the theory solver returns "satisfiable", we're done, yay. 187 | - If the theory solver returns "unsatisfiable", add a blocking clause to the Boolean abstraction, and try again with the SAT solver. 188 | 189 | **Q:** Do you see any problems with doing things this way? 190 | 191 | A: So, one problem that I see is that when you add the blocking clause to the Boolean abstraction, it rules out only _one particular assignment_. It will stop the solver from making _that same exact assignment_ again. But that's not very efficient. We might end up having to go through every single satisfying assignment, and then checking the formula that corresponds to that assignment using the theory solver. If there are a lot of satisfying assignments, that could be really slow. 192 | 193 | So ruling out one bad assignment at a time will work, eventually, but it will be slow. It would be really nice if we could add blocking clauses that would rule out large chunks of the space of assignments in one fell swoop. 194 | 195 | So for example, say you have this formula that's a big conjunction of a thousand literals: 196 | 197 | $x = y \land x < y \land l_1 \land l_2 \land \dots \land l_{998}$ 198 | 199 | We can tell by looking at this that it's unsatisfiable, because there's no way for the first two atoms to both be satisfiable. Regardless of what $l_1$ through $l_{998}$ are, we know that it's unsatisfiable. So a blocking clause that only rules out one of the assignments to the Boolean abstraction of this formula is not that helpful. 200 | 201 | We call $x = y \land x < y$ the _minimal unsatisfiable core_ of the formula. And it turns out you can compute these minimal unsatisfiable cores and add the negation of _them_ instead. 202 | 203 | ## Online and offline solving 204 | 205 | Lazy SMT solvers can be further subcategorized into **offline** and **online** solvers. I don't think the book uses this terminology, but it's used in other sources. 206 | 207 | - Offline lazy SMT solvers are SMT solvers where the theory solver treats the underlying SAT solver as a _black box_. What I mean by "black box" is that the interaction between the theory solver and the SAT solver consists of the theory solver waiting for the SAT solver to generate a complete satisfying assignment to the Boolean abstraction, and then checking whether the corresponding formula is satisfiable in the theory solver. What we just talked about doing above is offline solving. The book calls this the "Lazy-Basic" algorithm. 208 | - Online lazy SMT solvers have a tighter integration between the underlying SAT solver and the theory solver. And this is done by integrating the theory solver right into the CDCL loop. I *think* this is what the book calls this the "Lazy-CDCL" algorithm. 209 | 210 | In particular, suppose you're running CDCL and you've made a partial assignment in the Decide step and done BCP. Now, if there's no conflict, you can immediately invoke the theory solver on the formula corresponding to the *partial* assignment. If that turns out to be unsatisfiable in the theory solver, you can add its negation (the blocking clause) to the formula, just like you would normally add a conflict clause during CDCL. 211 | 212 | (Better yet, you can add the negation of the minimal unsatisfiable core.) 213 | -------------------------------------------------------------------------------- /lecture-notes/2019-10-11-introduction-to-smt-solving.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/lecture-notes/2019-10-11-introduction-to-smt-solving.pdf -------------------------------------------------------------------------------- /lecture-notes/2019-10-14-theories-equality-and-uninterpreted-functions.md: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | documentclass: extarticle 4 | fontsize: 17pt 5 | mainfont: Helvetica 6 | mathfont: Helvetica 7 | --- 8 | 9 | \newcommand{\satisfies}{\vDash} 10 | \newcommand{\integers}{\mathbb{Z}} 11 | \newcommand{\naturalnumbers}{\mathbb{N}} 12 | \newcommand{\true}{\mathrm{true}} 13 | \newcommand{\false}{\mathrm{false}} 14 | 15 | # Lecture notes for: Theories: Equality and uninterpreted functions 16 | 17 | Lindsey Kuper 18 | 19 | October 14, 2019 20 | 21 | These are lecture notes to accompany sections 3.1-3.4 (pp. 59-72) of Kroening and Strichman's _Decision Procedures: An Algorithmic Point of View_, second edition. See for the full collection of notes. 22 | 23 | ## Agenda 24 | 25 | - A simple decision procedure for equality logic 26 | - Uninterpreted functions 27 | - A decision procedure for EUF 28 | - Proving program equivalence with EUF 29 | 30 | ## A simple decision procedure for equality logic 31 | 32 | So last time, we started talking about the lazy paradigm of SMT solving, which involves interaction between a theory solver and a SAT solver, where the theory solver can solve formulas consisting of conjunctions of literals from a given theory, and the SAT solver does CDCL. 33 | 34 | (This, by the way, is in contrast to eager SMT solving, which is what the STP solver does, and we'll we talking about that on Friday.) 35 | 36 | But today, we're talking about lazy solving. Regardless of whether we're doing offline lazy solving or online lazy solving, we're going to need a theory solver. And most of Kroening and Strichman is devoted to the implementation of these theory solvers for various theories. 37 | 38 | So today, we're talking about solvers for the theory of equality, which we've brought up already. This theory lets you write formulas where the atoms are equalities, like this: 39 | 40 | $y = z \land \neg(x = z)$ 41 | 42 | **Q:** In the previous chapter, they sketched out a simple decision procedure for formulas like this. Does anyone remember what it was? 43 | 44 | A: So they said that you can turn it into a graph problem, where every variable is a node in a graph, and then you have two kinds of edges, equality edges and inequality edges. So we'd have a graph with three nodes --- a node each for $x$, $y$, and $z$ --- and an equality edge from $y$ to $z$ and an inequality edge from $x$ to $z$. Then the idea is that the formula is unsatisfiable if and only if you have two nodes that are connected by an inequality edge and also have a _path_ between them via equality edges. 45 | 46 | So, $y = z \land \neg(x = z)$ would be satisfiable, right? But if you had, say, 47 | 48 | $y = z \land \neg(x = z) \land x = y$ 49 | 50 | then that would be unsatisfiable, because there's an inequality edge from $x$ to $z$ and also an equality path from $x$ to $z$. 51 | 52 | **Q:** So, the book showed this just to make it clear right off the bat that a decision procedure actually exists for the conjunctive fragment of equality logic. But does anyone have any qualms about this particular decision procedure that they show? 53 | 54 | A: My qualm about it at first was that, well, sure, this decision procedure can tell you if the formula is satisfiable or not, but if it is satisfiable, it won't tell you what the satisfying assignment is. So the constructivist mathematician in me didn't like it much. But then I figured that after you determine satisfiability, you can construct a satisfying assignment. You'd do it like this: pick a node, pick an arbitrary value from the domain to assign to it. For anything reachable via equality edges, assign them the same value. Then pick a different arbitrary value from the domain, pick another node, and keep going. It should be fine and you shouldn't violate the inequality constraints as long as you keep picking a different domain value. 55 | 56 | It turns out it's actually a little more complicated than this, because constants from whatever domain you've chosen are allowed in equality logic, too: 57 | 58 | $y = z \lor (\neg(x = z) \land x = 2)$ 59 | 60 | In the book they say you can just replace every constant with a variable, and then for any constants that were different from each other, you add a new conjunct to the formula saying that those variables have to be different. When you do this, you get a formula that is satisfiable if the original formula was satisfiable, and unsatisfiable if the original formula was unsatisfiable. (The jargon for this is _equisatisfiable_. The old and new formulas are equisatisfiable if they're both satisfiable or both unsatisfiable.) So, the claim is that we don't have to worry about solving formulas that have constants in them, because we can construct an equisatisfiable formula without the constants. 61 | 62 | But, again, if you want to know more than just "yes, it's satisfiable" if it's satisfiable --- if you actually want to know the satisfying assignment --- then I think you would have to do something to keep the information around about which constants those were that you replaced with variables. It depends if "yes, it's satisfiable" is a good enough answer for you, or if you need to actually know the satisfying assignment. 63 | 64 | ## Uninterpreted functions 65 | 66 | This chapter is in fact not just about the theory of equality; it throws something else into the mix, which is the notion of _uninterpreted functions_. So now it's the "theory of equality and uninterpreted functions", or _EUF_ for short. 67 | 68 | This means that instead of just having atoms that look like $y = z$, the terms on either side of those equalities can now be function symbols that take terms as arguments. So for instance, $F(y) = z$ could be an atom. 69 | 70 | What does $F$ mean? We don't know what it means, and we don't care! All we know about $F$ is that if (say) $y = y'$, then $F(y) = F(y')$. This property is called _functional congruence_: instances of the same function return the same value if given equal arguments. Having uninterpreted functions in your theory means that you only care about functional congruence; you don't care about the semantics of functions otherwise. 71 | 72 | When you _do_ care about the semantics of functions, you have to add axioms to your theory to define their semantics. And that's called having interpreted functions. But if you don't care about the semantics then you just need functional congruence. 73 | 74 | Uninterpreted functions can also take multiple terms as arguments, and we can generalize the definiton of congruence in the expected way. So, $F(y, x) = F(z, q)$ if $y = z$ and $x = q$. 75 | 76 | **Q:** What's the purpose of having uninterpreted functions in a theory? 77 | 78 | A: It turns out that if you take all the interpreted functions in a theory and replace them with uninterpreted functions, and the formula is valid with just the uninterpreted functions, then that means it was also valid in the original version with interpreted functions. And it can be a lot easier to check for validity when you just have uninterpreted functions. So if you want to check for validity, one reasonable strategy is to convert interpreted functions to uninterpreted functions and then check for validity with an EUF solver. 79 | 80 | **Q:** What's the catch? 81 | 82 | A: Let $F$ be a formula with interpreted functions and let $F'$ be its EUF counterpart with uninterpreted functions (swapping any axioms that defined the semantics of functions for the functional congruence axiom), and suppose we have an EUF solver. Then: 83 | 84 | - If the EUF solver says $F'$ is valid, then $F$ is valid. 85 | - If the EUF solver says the formula is not valid, then we don't know: $F$ might be valid, or it might not. 86 | 87 | **Q:** What's an example of a time when the EUF solver might say that a formula is not valid when in fact it would have been valid if the functions were interpreted? 88 | 89 | A: So suppose that your formula is this: 90 | 91 | $x_1 = y_2 \land y_1 = x_2 \land (x_1 + y_1 = x_2 + y_2)$ 92 | 93 | So, is this formula valid? If we use the intended interpretation for $+$, then yes. But maybe we don't have a decision procedure for formulas with $+$ in them; maybe we only have an EUF decision procedure. So we translate the formula to EUF like so: 94 | 95 | $x_1 = y_2 \land y_1 = x_2 \land F(x_1, y_1) = F(x_2, y_2)$ 96 | 97 | And we have functional congruence of $F$ as part of EUF. So, is this formula valid in the EUF theory? No, it's not! Why not? 98 | 99 | What axiom about $+$ did we lose when we switched to $F$? We lost the fact that $+$ is _commutative_. Functional congruence alone won't help us, because $x_1$ and $x_2$ aren't necessarily equal and $y_1$ and $y_2$ aren't necessarily equal. 100 | 101 | **Q:** Did we lose soundness by switching from $+$ to $F$? 102 | 103 | A: Nope! We're not going to lie and claim a formula is valid when it isn't as a result of switching from $+$ to $F$. But we do lose completeness. If a formula is not valid after translation to EUF, that doesn't mean it wasn't valid originally. In other words, this solving approach is sound, but it's not complete. 104 | 105 | But, as we've discussed, sound but not complete isn't so bad. It just means that we're being conservative. And moreover, we can try checking for validity of $F'$ and then fall back to checking validity of $F$ if you have to. In fact, what we can do is start by trying to check for validity with the more abstract version of a formula and then _gradually_ add axioms or constraints if you aren't able to establish validity that way. This is called _abstraction-refinement_. 106 | 107 | That said, it's pretty common that you'd want to have properties like commutativity of addition expressible right from the get-go, in which case you would want to have a theory that lets you express addition. You might have heard of the theory "EUFA", which stands for "equality, uninterpreted functions, and arithmetic". We'll be reading some papers later in the course that use that theory. 108 | 109 | ## A decision procedure for EUF 110 | 111 | Back to EUF for now, though. So, how do we solve EUF formulas? The algorithm for this is called _congruence closure_ and is due to Robert Shostak, who published it in 1978. (Incidentally, Robert Shostak is also responsible for much of what we know about Byzantine fault tolerance. He's also the brother of Seth Shostak from the SETI Institute who does a lot of public speaking about aliens.) 112 | 113 | So here's the algorithm. You have a formula $F$ that's a conjunction of equalities over variables and uninterpreted functions. 114 | 115 | The steps of the algorithm are: 116 | 117 | 1. Put terms in an equivalence class together if you have a predicate saying they're equal; put all other terms in singleton equivalence classes 118 | 2. Merge equivalence classes that have a shared term; continue until none are left to be merged 119 | 3. (the "congruence closure" step) If terms $t_i$ and $t_j$ are in the same class, merge classes containing $F(t_i)$ and $F(t_j)$ for some $F$; continue until none are left to be merged 120 | 4. If there exists a disequality predicate $t_i \neq t_j$ such that $t_i$ and $t_j$ are in the same class, return "unsatisfiable", otherwise, return "satisfiable" 121 | 122 | So, for instance, say this is your $F$ (and this is from Kroening and Strichman, chapter 4): 123 | 124 | $x_1 = x_2 \land x_2 = x_3 \land x_4 = x_5 \land x_5 \neq x_1 \land F(x_1) \neq F(x_3)$ 125 | 126 | The first step is to put terms in an equivalence class together if you have a predicate saying they're equal. So, our equivalence classes are: 127 | 128 | $\{ \{ x_1, x_2 \}, \{ x_2, x_3 \}, \{ x_4, x_5 \}, \{ F(x_1) \}, \{ F(x_3) \} \}$ 129 | 130 | Now we can do step 2: 131 | 132 | $\{ \{ x_1, x_2, x_3 \}, \{ x_4, x_5 \}, \{ F(x_1) \}, \{ F(x_3) \} \}$ 133 | 134 | And now step 3: 135 | 136 | $\{ \{ x_1, x_2, x_3 \}, \{ x_4, x_5 \}, \{ F(x_1), F(x_3) \} \}$ 137 | 138 | But since $F(x_1)$ and $F(x_3)$ are in the same class, and we had the predicate $F(x_1) \neq F(x_3)$, this formula is unsatisfiable. 139 | 140 | It turns out that this is efficient to implement because all these subsets are disjoint, and there are data structures that are specifically designed for when you have a bunch of disjoint subsets of a set that periodically have to be merged. Those are known as _union-find_ data structures because they support an operation called "union" and an operation called "find", and you can read about that on your own if you want to. 141 | 142 | ## Proving program equivalence with EUF 143 | 144 | There's a lot you can express with just EUF. There are a couple examples of this in Kroening and Strichman that under the broad heading of _program equivalence_ problems. I use the term "program" broadly; by program equivalence problems we might mean: 145 | 146 | - proving that two implementations of a data structure providing the same API --- maybe a reference implementation and a fast, highly optimized implementation --- are interchangeable in terms of what they compute. 147 | - proving equivalence of two circuits, again, maybe a slow one and a fast one. 148 | - proving that the output of a compiler (or a phase of a compiler) computes the same thing as the input to the compiler (or phase) does. 149 | 150 | So let's just take the compiler correctness example from the book. Say we have the program: 151 | 152 | $z = (x_1 + y_1) * (x_2 + y_2)$ 153 | 154 | And there's a phase of compilation that flattens the code to: 155 | 156 | $u_1 = x_1 + y_1$ \newline 157 | $u_2 = x_2 + y_2$ \newline 158 | $z = u_1 * u_2$ 159 | 160 | which might have a more direct counterpart in assembly instructions. 161 | 162 | So what's the formula that we want to check validity of? 163 | 164 | We want to show that the value assigned to $z$ you get when you run the target program implies the assignment to $z$ you would get when your run the source program. 165 | 166 | $u_1 = x_1 + y_1 \land u_2 = x_2 + y_2 \land z = u_1 * u_2 \implies z = (x_1 + y_1) * (x_2 + y_2)$ 167 | 168 | This formula is called a _verification condition_. Coming up with verification conditions whose truth will imply the property we want to prove is a big part of the work of automated software verification. 169 | 170 | **Q:** By the way, why is this an implication and not an equivalence? And why does the implication go this way and not the other way? 171 | 172 | A: This is a little tricky. So the thing we're trying to prove is that, whatever value of $z$ the compiler produces, it's also a legitimate value of $z$ according to the source code. You can think of the source code as being a specification and the target code as being one particular implementation of that specification. In general (although maybe not for this toy example), there might be multiple ways to satisfy the _specification_ of the source code, and the compiler might implement only one of those ways. 173 | 174 | So, for example, and I'm completely making this up, the semantics of the language might tolerate a little bit of floating point error in the computation of $z$. And whatever the compiler produces has to be within those bounds. But if the compiler wants to have _tighter_ bounds on what it produces than the language spec does, that's okay. So we want a Venn diagram that looks like this: 175 | 176 | \begin{verbatim} 177 | 178 | -------------------------------------------- 179 | | | 180 | | values of z that satisfy source formula | 181 | | | 182 | | -------------------------------- | 183 | | | | | 184 | | | values of z that satisfy | | 185 | | | target formula | | 186 | | | | | 187 | | -------------------------------- | 188 | | | 189 | -------------------------------------------- 190 | 191 | \end{verbatim} 192 | 193 | And in general, when you have $A \subset B$, that means $x \in A \implies x \in B$: 194 | 195 | \begin{verbatim} 196 | 197 | -------------------------------------------- 198 | | | 199 | | B | 200 | | | 201 | | -------------------------------- | 202 | | | | | 203 | | | A | | 204 | | | | | 205 | | | | | 206 | | -------------------------------- | 207 | | | 208 | -------------------------------------------- 209 | 210 | \end{verbatim} 211 | 212 | OK, so we want to prove that our verification condition is valid, but we only have an EUF decision procedure. We can turn those into uninterpreted functions, though. 213 | 214 | So instead of 215 | 216 | $u_1 = x_1 + y_1 \land u_2 = x_2 + y_2 \land z = u_1 * u_2 \implies z = (x_1 + y_1) * (x_2 + y_2)$ 217 | 218 | we have: 219 | 220 | $u_1 = F(x_1, y_1) \land u_2 = F(x_2, y_2) \land z = G(u_1, u_2) \implies z = G(F(x_1, y_1), F(x_2, y_2))$ 221 | 222 | which is a formula that we can convert to CNF and hand off to our EUF decision procedure. If it's valid according to that decision procedure, then the original formula was valid, too. 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /lecture-notes/2019-10-14-theories-equality-and-uninterpreted-functions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/lecture-notes/2019-10-14-theories-equality-and-uninterpreted-functions.pdf -------------------------------------------------------------------------------- /lecture-notes/2019-10-16-theories-linear-arithmetic.md: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | documentclass: extarticle 4 | fontsize: 17pt 5 | mainfont: Helvetica 6 | mathfont: Helvetica 7 | --- 8 | 9 | \newcommand{\satisfies}{\vDash} 10 | \newcommand{\integers}{\mathbb{Z}} 11 | \newcommand{\naturalnumbers}{\mathbb{N}} 12 | \newcommand{\true}{\mathrm{true}} 13 | \newcommand{\false}{\mathrm{false}} 14 | 15 | # Lecture notes for: Theories: Linear arithmetic 16 | 17 | Lindsey Kuper 18 | 19 | October 16, 2019 20 | 21 | These are lecture notes to accompany sections sections 5.1-5.2 (pp. 97-106) of Kroening and Strichman's _Decision Procedures: An Algorithmic Point of View_, second edition. See for the full collection of notes. 22 | 23 | ## Agenda 24 | 25 | - Flavors of linear arithmetic 26 | - The simplex algorithm for solving linear real arithmetic formulas 27 | 28 | ## Flavors of linear arithmetic 29 | 30 | Last time we looked at the theory of equality and uninterpreted functions, or EUF, and we talked about how one strategy for solving formulas with functions in it, like, say, addition or multiplication, is to turn those functions into uninterpreted functions and then use an EUF solver. This works well for many applications. But as we saw, we lose meaning when we do this, and sometimes we do actually want to be able to reason about arithmetic. 31 | 32 | A linear arithmetic formula might be something like this: 33 | 34 | $2z_1 + 3z_2 \leq 5 \land z_2 + 5z_2 - 10z_3 \geq 6 \land z_1 + z_3 = 3$ 35 | 36 | (I don't actually know if this is satisfiable; I'm just making something up.) 37 | 38 | In linear arithmetic formulas, we can multiply variables by constants, but we can't multiply variables by each other. Hence the name "linear arithmetic". If you want to be able to multiply variables, that's called nonlinear arithmetic. Decision procedures do exist for various nonlinear arithmetic theories, but those are beyond the scope of this lecture. 39 | 40 | There are various linear arithmetic theories, depending on the domain that the constants and variables come from. If the domain in question is real numbers, then the theory is called _linear real arithmetic_. 41 | 42 | In practice, though, when we speak of linear "real" arithmetic solvers, the numbers involved are _rational_ numbers. And I'll follow that convention too: whenever I say "linear real arithmetic" you can assume that the numbers are actually rational unless otherwise specified. 43 | 44 | So you can assume that that the constants in the input formula are all rational numbers. (In my example above, they're actually all integral numbers.) And you can assume that the domain of variables is rational numbers, too. If a linear arithmetic formula with rational constants is satisfiable, there will exist a satisfying assignment of variables to rational numbers. So "linear real arithmetic" is a misnomer, and we should really say "linear rational arithmetic" --- but "linear real arithmetic" is what people say, so we'll follow that convention too. 45 | 46 | (There are solvers that handle irrational numbers, but they're beyond the scope of this lecture, and for the software and hardware verification applications that we're concerned with, for the most part we don't need irrational numbers.) 47 | 48 | What if the domain is _integers_? Then the theory is called linear integer arithmetic, sometimes also called Presburger arithmetic. (To be pedantic, it's the _quantifier-free fragment_ of Presburger arithmetic.) 49 | 50 | **Q:** By the way, which do you think is computationally harder to solve, linear real arithmetic formulas or linear integer arithmetic formulas? 51 | 52 | A: Linear integer arithmetic formulas are harder to solve. I found this somewhat mind-bending when I learned about it, because I'm used to thinking that integers are easier to deal with than real numbers. I'm a programming languages person! I'm allergic to real numbers! I like my numbers to be integral (and ideally non-negative)! 53 | 54 | But on further reflection, it makes sense that coming up with satisfying assignments that are integral would be harder than coming up with satisfying assignments that are rational. For instance, if the formula is 55 | 56 | $5z_1 + 3z_2 = 4$ 57 | 58 | then it's pretty straightforward to come up with a satisfying assignment to $z_1$ and $z_2$ that's rational. We can assign them both $0.5$, for instance. But if we need to come up with a satisfying assignment that's integral, we can't do it. So yeah, solving linear integer arithmetic formulas is an NP-complete problem, while solving linear real arithmetic formulas can be done, it turns out, in polynomial time. 59 | 60 | ## The simplex algorithm for solving linear real arithmetic formulas 61 | 62 | The algorithm that we're going to look at for solving linear real arithmetic formulas is called the _simplex algorithm_. It is, in fact, _not_ a polynomial-time algorithm for solving this problem, although polynomial-time algorithms do exist. It's worst-case exponential. But it nevertheless turns out to be the algorithm that's most efficient in practice on real inputs. 63 | 64 | So you may have heard of the simplex algorithm before, not necessarily in the context of SMT solving, but in the context of solving what are known as _linear programming_ problems, or _LP_ problems for short. 65 | 66 | A standard introduction to LP problems is the ["diet problem"](http://ftp.mcs.anl.gov/pub/tech_reports/reports/P602.pdf). The idea is that you want to minimize the cost of the food you eat in a day, subject to constraints on how many calories you need to eat and what your nutritional requirements are. 67 | 68 | To make it really simple, let's assume there are three foods: corn, milk, and bread. Each food has a certain cost per serving and a certain number of calories per serving, and it provides a certain amount of, say, vitamin A: 69 | 70 | * A serving of corn costs 18 cents, has 107 units of vitamin A, and is 72 calories. 71 | * A serving of milk costs 23 cents, has 500 units of vitamin A, and is 121 calories. 72 | * A serving of bread costs 5 cents, has 0 units of vitamin A, and is 65 calories. 73 | 74 | This example is clearly a bit contrived, but let's go with it. 75 | 76 | So let's say you want to eat between 2000 and 2250 calories in a day, and furthermore, you want to get between 5000 and 50,000 units of vitamin A per day. 77 | 78 | So the question is, how many servings of each food should you eat to minimize the cost? 79 | 80 | OK, so what do the constraints look like? 81 | 82 | So let's set up three variables, $x_1$, $x_2$, and $x_3$, which are the numbers of servings we eat of corn, milk, and bread, respectively. So the cost of a day's food would be 83 | 84 | $18x_1 + 23x_2 + 5x_3$ 85 | 86 | and that's the number we want to minimize. But we need to make sure we get at least 2000 calories and no more than 2250: 87 | 88 | $2000 \leq 72x_1 + 121x_2 + 65x_3 \leq 2250$ 89 | 90 | and betwen 5000 and 50,000 units of vitamin A: 91 | 92 | $5000 \leq 107x_1 + 500x_2 \leq 50,000$ 93 | 94 | So in general, a linear programming problem is the problem of minimizing or maximizing a linear function called the _objective function_ --- in this case the function is $f(x_1, x_2, x_3) = 18x_1 + 23x_2 + 5x_3$ --- subject to some number of _linear constraints_. Here, the linear constraints happen to be inequalities, but they could also be equalities. For example, we could have the constraint that you eat _precisely_ 2250 calories a day: 95 | 96 | $72x_1 + 121x_2 + 65x_3 = 2250$ 97 | 98 | Or we could have the constraint that you eat precisely five servings of corn: 99 | 100 | $x_1 = 5$ 101 | 102 | So, this is an optimization problem, right? It's a problem of minimizing or maximizing a function. 103 | 104 | Here's another example. So say you're a farmer and you have $L$ square kilometers of land that you could plant with either wheat or barley or some combination. You have $F$ kilograms of fertilizer and $P$ kilograms of pesticide. 105 | 106 | Every square kilometer of wheat requires $F_1$ kilograms of fertilizer and $P_1$ kilograms of pesticide, while every square kilometer of barley requires $F_2$ kilograms of fertilizer and $P_2$ kilograms of pesticide. 107 | 108 | Let $S_1$ be the selling price of wheat per square kilometer, and $S_2$ be the selling price of barley. If we denote the area of land planted with wheat and barley by $x_1$ and $x_2$ respectively, then profit can be maximized by choosing optimal values for $x_1$ and $x_2$. 109 | 110 | So in other words, the function we want to maximize is 111 | 112 | $S_1 x_1 + S_2 x_2$ 113 | 114 | subject to the constraints on how much land we have: 115 | 116 | $x_1 + x_2 \leq L$ 117 | 118 | and on how much fertilizer and pesticide we have: 119 | 120 | $F_1 x_1 + F_2 x_2 \leq F$ 121 | 122 | $P_1 x_1 + P_2 x_2 \leq P$ 123 | 124 | **Q:** Any other constraints we need? 125 | 126 | A: We can't plant a negative area with a crop, so we have some constraints that $x_1$ and $x_2$ have to be nonnegative: 127 | 128 | $x_1 \geq 0$ 129 | 130 | $x_2 \geq 0$ 131 | 132 | This is another optimization problem, right? A problem of maximizing a function. And the simplex algorithm is a recipe for doing that. 133 | 134 | It's an algorithm that you can carry out by hand if you want to, or you can use an off-the-shelf LP solver that uses some version of the simplex algorithm to find an optimal solution. An open-source LP solver is GLPK, for example; a closed-source commercial one is Gurobi. 135 | 136 | **Q:** But wait a second. This course isn't about optimization problems, it's about decision problems, right? We just want to know if formulas are satisfiable or not. We don't care if they're a little bit satisfiable or a lot satisfiable; we just want to know if they're satisfiable. So why is the simplex algorithm of interest to us? 137 | 138 | As it's normally presented, the simplex algorithm has two phases. The first phase involves finding what's called a _feasible solution_ to the problem, in which all the constraints are satisfied. For instance, finding a feasible solution to our diet problem would mean coming up with values for $x_1$, $x_2$, and $x_3$ such that all these linear constraints are true. 139 | 140 | Once that's done, you can move onto the second phase of the algorithm, which involves iterating toward an _optimal_ solution that minimizes the objective function. 141 | 142 | Many presentations of the simplex algorithm assume that you already have a feasible solution, and they _only_ deal with optimizing the objective function. Because I don't actually have time to teach it today, I'm going to ask you to trust me that once you know that a feasible solution exists, then it's possible to optimize it. So just assume, for today, that there exists an algorithm for turning feasible solutions into optimal ones. 143 | 144 | For many real-world LP problems, assuming you have a feasible solution to begin with is a realistic assumption to make. For instance, suppose you're the farmer from the example problem above. Whatever you're already doing is a feasible solution: assuming you've set up the problem correctly, the amounts of fertilizer, pesticide, and land you're using already fall within the constraints, because it would be impossible for you to do otherwise (for instance, you can't use more land than exists, or put a negative amount of fertilizer on it). Of course, what you're currently doing is probably not *optimal*, which is why you need the simplex algorithm! But at least you have an initial feasible solution from which to start iterating toward an optimal one. 145 | 146 | So, many presentations of the simplex algorithm focus on the second phase only. But we want to do the opposite: we only care about coming up with the feasible solution in the first place. In other words, we only care about phase one of the algorithm. And _that_ problem really is a decision problem. It's a yes-or-no question: is there a feasible solution, or isn't there? 147 | 148 | And by this point you might have realized that the problem of finding an initial feasible solution to a linear programming problem coincides exactly with the problem of finding a satisfying assignment to a linear real arithmetic formula that consists of a _conjunction of linear constraints_. For instance, for our diet problem, the formula would be: 149 | 150 | $(72x_1 + 121x_2 + 65x_3 \geq 2000) \land (72x_1 + 121x_2 + 65x_3 \leq 2250) \land (107x_1 + 500x_2 \geq 5000) \land (107x_1 + 500x_2 \leq 5000)$ 151 | 152 | Determining whether this formula is satisfiable is exactly the same problem as determining if there is a feasible solution to the linear programming problem. (Notice that we left the objective function out of the formula, because we don't need it.) 153 | 154 | Strangely enough, it turns out that you can use essentially the same algorithm that you use for phase two of the simplex algorithm, which is the optimization part, to carry out phase one, which is the decision part. You just have to turn the decision problem into an optimization problem. 155 | 156 | OK. So in particular we're going to be talking about LP problems in a particular form. 157 | 158 | maximize $c_1 x_1 + c_2 x_2 + \dots + c_n x_n$ 159 | 160 | subject to some number of constraints that are all of the form 161 | 162 | $a_1 x_1 + a_2 x_2 + \dots + a_n x_n \leq b$ 163 | 164 | plus some special constraints called _nonnegativity_ constraints on all the variables: 165 | 166 | $x_1 \geq 0$, $x_2 \geq 0$, $dots$, $x_n \geq 0$ 167 | 168 | (The nonnegativity constraints are like the ones that ensure that we don't plant a negative area with wheat or barley.) 169 | 170 | Now, _all_ we care about is whether this problem has a feasible solution. We don't care about the objective function. So we're going to _throw away_ that objective function, and instead we're going to make a slight tweak to our constraints and throw in a new variable called $x_0$. 171 | 172 | $a_1 x_1 + a_2 x_2 + \dots + a_n x_n - x_0 \leq b$ 173 | 174 | And we'll throw in a new nonnegativity constraint on $x_0$ also: 175 | 176 | $x_0 \geq 0$ 177 | 178 | This new problem is called an _auxiliary problem_. 179 | 180 | So $x_0$ can be zero, but it can't be nonnegative. Now the problem becomes: _minimize $x_0$_. We _want_ $x_0$ to be zero, because we can see that the original problem has a feasible solution _if and only if_ this new problem has a solution where $x_0 = 0$. 181 | 182 | So we turned the decision problem of finding a feasible solution into the optimization problem of minimizing $x_0$. 183 | 184 | **Q:** Now, the key question: Does the _auxiliary_ problem have a feasible solution? 185 | 186 | A: Yes, it does! We just set all the $x_1$ through $x_n$ to 0 and then we make $x_0$ something sufficiently large. So we have a feasible solution to the _auxiliary_ problem, and now we just need to iterate toward an optimal one where $x_0$ is zero. But we have a way to get that! We just use the algorithm that I mentioned earlier that I asked you to trust me exists! 187 | 188 | By the way, my way of explaining this is different from what Kroening and Strichman do. They formulate the problem differently, and they show what they call the "general simplex" algorithm, where you don't use an objective function at all. But I want to show it in a way that I understand better, and is also closer to what's presented in the Reluplex paper which we'll read later in the course. Your mileage may vary. 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /lecture-notes/2019-10-16-theories-linear-arithmetic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/lecture-notes/2019-10-16-theories-linear-arithmetic.pdf -------------------------------------------------------------------------------- /lecture-notes/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for file in *.md; do 4 | pandoc --pdf-engine=xelatex $file -o "${file%.md}.pdf" 5 | done 6 | -------------------------------------------------------------------------------- /presentations/Putting Consistency Back into Eventual Consistency 11_20.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/presentations/Putting Consistency Back into Eventual Consistency 11_20.pdf -------------------------------------------------------------------------------- /presentations/README.md: -------------------------------------------------------------------------------- 1 | This directory is for final versions of presentation materials. You may optionally upload your presentation materials here. 2 | -------------------------------------------------------------------------------- /presentations/kaplan-presentation-final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/presentations/kaplan-presentation-final.pdf -------------------------------------------------------------------------------- /presentations/klee-presentation-final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/presentations/klee-presentation-final.pdf -------------------------------------------------------------------------------- /presentations/liquid_types.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/presentations/liquid_types.pdf -------------------------------------------------------------------------------- /presentations/refinement_types_for_haskell.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lkuper/CSE290Q-2019-09/849dd968cbfdb314bcce054e83775ec4a37b7584/presentations/refinement_types_for_haskell.pdf -------------------------------------------------------------------------------- /readings.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Readings" 3 | layout: single 4 | classes: wide 5 | --- 6 | 7 | ## Current schedule of readings 8 | 9 | This list is subject to change, and it is neither sound (i.e., if something's listed here, that doesn't mean we'll read it) nor complete (i.e., if something's *not* listed here, that doesn't mean we *won't* read it). 10 | 11 | Links in the "Topic" column for the first three weeks of class link to lecture notes for those topics. After that, we'll dispense with the lecture format and move to student presentations. 12 | 13 | | Date | Topic | Presenter | Reading 14 | |------------------|------------------------------------------------|----------------------|----------------------------------------------------- 15 | | Friday, 9/27 | [Course overview](course-overview.html) | Lindsey | (none) 16 | | Monday, 9/30 | ["The science of brute force"](lecture-notes/2019-09-30-the-science-of-brute-force.pdf) | Lindsey | Marijn J. H. Heule and Oliver Kullmann, [The science of brute force (CACM 2017)](https://dl.acm.org/citation.cfm?id=3107239) 17 | | Wednesday, 10/2 | [Introduction to decision procedures, part 1](lecture-notes/2019-10-02-introduction-to-decision-procedures-1.pdf) | Lindsey | Sections 1.0-1.3 (pp. 1-14) of Daniel Kroening and Ofer Strichman, [_Decision Procedures: An Algorithmic Point of View_, second edition (2016)](https://link.springer.com/book/10.1007%2F978-3-662-50497-0) ([off-campus access link](https://link-springer-com.oca.ucsc.edu/book/10.1007%2F978-3-662-50497-0)) 18 | | Friday, 10/4 | [Introduction to decision procedures, part 2](lecture-notes/2019-10-04-introduction-to-decision-procedures-2.pdf) | Lindsey | Sections 1.4-1.7 (pp. 14-23) of Kroening and Strichman 19 | | Monday, 10/7 | [Introduction to SAT solving, part 1](lecture-notes/2019-10-07-introduction-to-sat-solving-1.pdf) | Lindsey | Sections 2.1-2.2.3 (pp. 27-38) of Kroening and Strichman 20 | | Wednesday, 10/9 | **Class cancelled due to power outage (please read lecture notes anyway)**
[Introduction to SAT solving, part 2](lecture-notes/2019-10-09-introduction-to-sat-solving-2.pdf) | Lindsey | Sections 2.2.4-2.2.9 (pp. 38-50) of Kroening and Strichman 21 | | Friday, 10/11 | [Introduction to SMT solving](lecture-notes/2019-10-11-introduction-to-smt-solving.pdf) | Lindsey | Sections 3.1-3.4 (pp. 59-72) of Kroening and Strichman 22 | | Monday, 10/14 | [Theories: Equality and uninterpreted functions](lecture-notes/2019-10-14-theories-equality-and-uninterpreted-functions.pdf) | Lindsey | Sections 4.1-4.5 (pp. 77-91) of Kroening and Strichman 23 | | Wednesday, 10/16 | [Theories: Linear arithmetic](lecture-notes/2019-10-16-theories-linear-arithmetic.pdf) | Lindsey | Sections 5.1-5.2 (pp. 97-106) of Kroening and Strichman 24 | | Friday, 10/18 | Solver-aided systems | Samuel | Cristian Cadar et al., [EXE: automatically generating inputs of death (CCS 2006)](https://web.stanford.edu/~engler/exe-ccs-06.pdf) 25 | | Monday, 10/21 | Solver design and implementation | Will | Vijay Ganesh and David L. Dill, [A decision procedure for bit-vectors and arrays (CAV 2007)](https://link.springer.com/chapter/10.1007/978-3-540-73368-3_52) ([off-campus access link](https://link-springer-com.oca.ucsc.edu/chapter/10.1007/978-3-540-73368-3_52)) 26 | | Wednesday, 10/23 | Solver design and implementation | Clara | Adam Kiezun et al., [HAMPI: a solver for string constraints (ISSTA 2009)](http://people.csail.mit.edu/akiezun/issta54-kiezun.pdf) 27 | | Friday, 10/25 | Solver-aided systems | Matthew | Cristian Cadar, Daniel Dunbar, and Dawson Engler, [KLEE: unassisted and automatic generation of high-coverage tests for complex systems programs (OSDI 2008)](https://www.usenix.org/legacy/events/osdi08/tech/full_papers/cadar/cadar.pdf) 28 | | Monday, 10/28 | **Class cancelled due to power outage** 29 | | Wednesday, 10/30 | Solver-aided languages | Akhil, David | Richard Uhler and Nirav Dave, [Smten with satisfiability-based search (OOPSLA 2014)](https://dl.acm.org/citation.cfm?id=2714064.2660208) ([off-campus access link](https://dl-acm-org.oca.ucsc.edu/citation.cfm?id=2714064.2660208)); Emina Torlak and Rastislav Bodik, [Growing solver-aided languages with Rosette (Onward! 2013)](https://homes.cs.washington.edu/~emina/pubs/rosette.onward13.pdf) 30 | | Friday, 11/1 | Solver-aided systems **(2-page project proposals due EOD)** | Guest lecture: [Mangpo Phothilimthana (Google Brain)](https://mangpo.net/) | Phitchaya Mangpo Phothilimthana et al., [Swizzle Inventor: Data Movement Synthesis for GPU Kernels (ASPLOS 2019)](https://mangpo.net/papers/swizzle-inventor-asplos19.pdf) 31 | | Monday, 11/4 | Solver design and implementation | Zehui | Cunjing Ge et al., [SMT solving for the theory of ordering constraints (LCPC 2015)](https://link.springer.com/chapter/10.1007/978-3-319-29778-1_18) ([off-campus access link](https://link-springer-com.oca.ucsc.edu/chapter/10.1007/978-3-319-29778-1_18)) 32 | | Wednesday, 11/6 | Solver-aided languages | Gan | Patrick M. Rondon, Ming Kawaguci, and Ranjit Jhala, [Liquid types (PLDI 2008)](https://dl.acm.org/citation.cfm?id=1375602) ([off-campus access link](https://dl-acm-org.oca.ucsc.edu/citation.cfm?id=1375602)) 33 | | Friday, 11/8 | Solver-aided languages | Akhil | K. Rustan M. Leino, [Dafny: an automatic program verifier for functional correctness (LPAR 2010)](https://link.springer.com/chapter/10.1007/978-3-642-17511-4_20) ([off-campus access link](https://link-springer-com.oca.ucsc.edu/chapter/10.1007/978-3-642-17511-4_20)) 34 | | Monday, 11/11 | No class (Veterans Day) 35 | | Wednesday, 11/13 | **Class cancelled due to strike** 36 | | Friday, 11/15 | Solver-aided languages | Guest lecture: [James Bornholt (UT Austin)](https://www.cs.utexas.edu/~bornholt/) | James Bornholt and Emina Torlak, [Finding code that explodes under symbolic evaluation (OOPSLA 2018)](https://www.cs.utexas.edu/~bornholt/papers/sympro-oopsla18.pdf) 37 | | Monday, 11/18 | Solver-aided languages **(Project status update week begins)** | Matthew, Gan | Ali Sinan Köksal, Viktor Kuncak, and Philippe Suter, [Constraints as control (POPL 2012)](https://dl.acm.org/citation.cfm?id=2103675) ([off-campus access link](https://dl-acm-org.oca.ucsc.edu/citation.cfm?id=2103675)); Niki Vazou et al., [Refinement types for Haskell (ICFP 2014)](https://dl.acm.org/citation.cfm?id=2628161) ([off-campus access link](https://dl-acm-org.oca.ucsc.edu/citation.cfm?id=2628161)) 38 | | Wednesday, 11/20 | Solver-aided systems | David | Valter Balegas et al., [Putting consistency back into eventual consistency (EuroSys 2015)](https://dl.acm.org/citation.cfm?id=2741972) ([off-campus access link](https://dl-acm-org.oca.ucsc.edu/citation.cfm?id=2741972)) 39 | | Friday, 11/22 | Solver-aided systems **(Project status update week ends)** | Clara | KC Sivaramakrishnan, Gowtham Kaki, and Suresh Jagannathan, [Declarative Programming over Eventually Consistent Data Stores (PLDI 2015)](http://kcsrk.info/papers/quelea_pldi15.pdf) 40 | | Monday, 11/25 | Solver-aided systems | Zehui | Pavel Panchekha and Emina Torlak, [Automated reasoning for web page layout (OOPSLA 2016)](https://dl.acm.org/citation.cfm?id=2984010) 41 | | Wednesday, 11/27 | Solver design and implementation | Will | Guy Katz et al., [Reluplex: an efficient SMT solver for verifying deep neural networks (CAV 2017)](https://link.springer.com/chapter/10.1007/978-3-319-63387-9_5) ([extended version on arXiv](https://arxiv.org/pdf/1702.01135.pdf)) 42 | | Friday, 11/30 | No class (Thanksgiving) 43 | | Monday, 12/2 | Solver-aided systems | Samuel | Luke Nelson et al., [Hyperkernel: push-button verification of an OS kernel (SOSP 2017)](https://unsat.cs.washington.edu/papers/nelson-hyperkernel.pdf) 44 | | Wednesday, 12/4 | 15-minute project presentations | Zehui, Will, David, Gan 45 | | Friday, 12/6 | 15-minute project presentations **(Project reports due EOD)** | Samuel, Clara, Matthew, Akhil 46 | | Thursday, 12/12 | ~~final exam~~ end-of-quarter celebration at 10am | **(special location: [the LSD lab](https://twitter.com/lindsey/status/1050482295126126592) (Engineering 2, Room 398))** | 47 | 48 | ## Further reading 49 | 50 | ### The first three weeks 51 | 52 | We'll mostly assume that you are familiar with the basics of **propositional logic**, but if you need a refresher, look at [Chapter 1 (Propositional Logic) of _The Calculus of Computation: Decision Procedures with Applications to Verification_ (2007)](https://link.springer.com/chapter/10.1007/978-3-540-74113-8_1) by Aaron R. Bradley and Zohar Manna ([off-campus access link](https://link-springer-com.oca.ucsc.edu/chapter/10.1007/978-3-540-74113-8_1)). Bradley and Manna's book is also a good alternative resource for many of the other topics covered in Kroening and Strichman. 53 | 54 | The [_Handbook of Satisfiability_ (2009)](https://www.iospress.nl/book/handbook-of-satisfiability/) [(off-campus access link to online edition)](https://ebookcentral-proquest-com.oca.ucsc.edu/lib/ucsc/detail.action?docID=448770), edited by A. Biere, M. Heule, H. van Maaren, and T. Walsh, is an excellent reference for many topics we'll be covering in the first three weeks of class. 55 | 56 | A couple of slightly older CACM articles, in addition to the one we have as an assigned reading, provide an approachable overview of SAT and SMT: 57 | 58 | - Sharad Malik and Lintao Zhang, [Boolean satisfiability: from theoretical hardness to practical success (CACM 2009)](https://dl.acm.org/citation.cfm?id=1536637) 59 | - Leonardo de Moura and Nikolaj Bjørner, [Satisfiability modulo theories: introduction and applications (CACM 2011)](https://dl.acm.org/citation.cfm?id=1995394) ([off-campus access link](https://dl-acm-org.oca.ucsc.edu/citation.cfm?doid=1995376.1995394)) 60 | 61 | Many solver-aided languages and systems rely on the Z3 SMT solver. The standard citation is: Leonardo de Moura and Nikolaj Bjørner, [Z3: an efficient SMT solver (TACAS 2008)](https://link.springer.com/chapter/10.1007/978-3-540-78800-3_24) ([off-campus access link](https://link-springer-com.oca.ucsc.edu/chapter/10.1007/978-3-540-78800-3_24)). If you want to become familiar with Z3, check out the [tutorial](http://theory.stanford.edu/~nikolaj/programmingz3.html) and [interactive guide](https://rise4fun.com/Z3/tutorial/guide). 62 | 63 | Are you bored of academic papers about SMT? Dennis Yurichev's [SAT/SMT by Example](https://yurichev.com/writings/SAT_SMT_by_example.pdf) is impressive and fun. 64 | 65 | ### The rest of the course 66 | 67 | There's a vast amount of reading material that would be in scope for a course on SMT solving and solver-aided systems, but that this particular course won't have time to cover, including but not limited to: 68 | 69 | - ...material on answer set programming systems with integrated solvers, such as: 70 | - Martin Gebser et al., [Potassco: the Potsdam answer set solving collection (_AI Communications_, 2011)](https://dl.acm.org/citation.cfm?id=1971623) ([off-campus access link](https://web-b-ebscohost-com.oca.ucsc.edu/ehost/pdfviewer/pdfviewer?vid=1&sid=4bf38049-468d-4ddd-840e-4795b3e5829a%40pdc-v-sessmgr01)) (see also: [the Potassco website](https://potassco.org/)) 71 | - ...more work on solver-based [superoptimizing](https://en.wikipedia.org/wiki/Superoptimization) compilers, such as these papers (which are [John Regehr](https://www.cs.utah.edu/~regehr/)'s and JF Bastien's recommendations): 72 | - Sorav Bansal and Alex Aiken, [Automatic generation of peephole superoptimizers (ASPLOS 2006)](https://theory.stanford.edu/~aiken/publications/papers/asplos06.pdf) 73 | - Sumit Gulwani et al., [Synthesis of loop-free programs (PLDI 2011)](https://dl.acm.org/citation.cfm?id=1993506) ([off-campus access link](https://dl-acm-org.oca.ucsc.edu/citation.cfm?id=1993506)) 74 | - Sebastian Buchwald, [OPTGEN: a generator for local optimizations (CC 2015)](https://link.springer.com/chapter/10.1007/978-3-662-46663-6_9) ([off-campus access link](https://link-springer-com.oca.ucsc.edu/content/pdf/10.1007%2F978-3-662-46663-6_9.pdf)) 75 | - Eric Schkufza, Rahul Sharma, and Alex Aiken, [Stochastic superoptimization (ASPLOS 2013)](https://cs.stanford.edu/people/eschkufz/docs/asplos_13.pdf) 76 | - ...more work on integration between a language and a solver, such as: 77 | - Emina Torlak and Rastislav Bodik, [A lightweight symbolic virtual machine for solver-aided host languages (PLDI 2014)](https://homes.cs.washington.edu/~emina/doc/rosette.pldi14.pdf) (the follow-up to the Onward 2013 Rosette paper we're reading) 78 | - Aaron Bembenek and Stephen Chong, [FormuLog: Datalog for static analysis involving logical formulae (2018)](https://arxiv.org/abs/1809.06274) 79 | - Trevor Elliott et al., [Guilt free Ivory (Haskell Symposium 2015)](https://dl.acm.org/citation.cfm?id=2804318) ([off-campus access link](https://dl-acm-org.oca.ucsc.edu/citation.cfm?id=2804318)) 80 | - William T. Hallahan, Anton Xue, and Ruzica Piskac, [G2Q: Haskell constraint solving (Haskell Symposium 2019)](http://www.cs.yale.edu/homes/piskac/papers/2019HallahanETALquasiquoter.pdf) 81 | - ...more work on solver design and implementation, such as: 82 | - Robert Brummayer and Armin Biere, [Boolector: an efficient SMT solver for bit-vectors and arrays (TACAS 2009)](http://fmv.jku.at/papers/BrummayerBiere-TACAS09.pdf) (see also: [many related publications from the Boolector team](https://boolector.github.io/publications.html)) 83 | - ...more work on solver-aided systems for ensuring consistency in distributed systems, such as: 84 | - Farzin Houshman and Mohsen Lesani, [Hamsaz: replication coordination analysis and synthesis (POPL 2019)](https://dl.acm.org/citation.cfm?doid=3302515.3290387) 85 | - solver-aided systems for bug-finding and fault injection, such as: 86 | - Peter Alvaro, Joshua Rosen, and Joseph M. Hellerstein, [Lineage-driven fault injection (SIGMOD 2015)](https://people.ucsc.edu/~palvaro/molly.pdf) 87 | - ...follow-up work on Reluplex, such as: 88 | - Guy Katz et al., [The Marabou framework for verification and analysis of deep neural networks (CAV 2019)](https://link.springer.com/content/pdf/10.1007%2F978-3-030-25540-4_26.pdf) 89 | - ...recent creative applications of SMT solvers across subfields of CS, such as: 90 | - Emma Tosch et al., [PlanAlyzer: assessing threats to the validity of online experiments (OOPSLA 2019)](https://arxiv.org/abs/1909.13649) 91 | - Gabrielle Beck, Maximilian Zinkus, and Matthew Green, [Using SMT solvers to automate chosen ciphertext attacks (2019)](https://eprint.iacr.org/2019/958) 92 | - Etc., etc., etc. 93 | --------------------------------------------------------------------------------