Skip to main content
  (Week 1)

Setup, Exercises, and What Comes Next

Your first hands-on session: get your tools working, write your first Z3 programs, and learn how the course operates.

Getting Set Up

Before you can work with Z3, you need Python 3.10 or later and the z3-solver package. Follow the instructions on the Setup page.

Once you have everything installed, test it with this quick check:

hello-z3.py
from z3 import Int, Solver, sat

x = Int('x')
s = Solver()
s.add(x > 0, x < 10)
if s.check() == sat:
    print("sat:", s.model())

If you see sat: followed by a value for x, you are good to go.

If you get stuck: pair up with a neighbor, or ask a TA. If your laptop has restrictions that block installation, let us know and we will help you find a workaround.

Exercise 1: Rabbits and Chickens

A farmer has some rabbits and some chickens. There are 20 heads and 56 legs total. How many of each?

Try writing this yourself before looking at the solution. The pattern is always the same: declare variables, state constraints, solve.

rabbits.py
from z3 import Int, Solver, sat

rabbits = Int('rabbits')
chickens = Int('chickens')

s = Solver()
s.add(rabbits >= 0)
s.add(chickens >= 0)
s.add(rabbits + chickens == 20)
s.add(4 * rabbits + 2 * chickens == 56)

if s.check() == sat:
    print(s.model())
else:
    print("No solution!")

Extensions to try:

Exercise 2: Shapes Puzzle

A classic puzzle (adapted from Dennis Yurichev's SAT/SMT by Example):

Solve for circle, square, and triangle.

shapes.py
from z3 import Int, Solver, sat

circle = Int('circle')
square = Int('square')
triangle = Int('triangle')

s = Solver()
s.add(circle + circle == 10)
s.add(circle * square + square == 12)
s.add(circle * square - triangle == circle)

if s.check() == sat:
    m = s.model()
    print(f"circle = {m[circle]}")
    print(f"square = {m[square]}")
    print(f"triangle = {m[triangle]}")

Notice the pattern is the same: declare, constrain, solve. You can encode any puzzle, any system of equations, any constraint satisfaction problem this way.

Exercise 3: Try Your Own Reduction (Stretch)

If you finished the exercises above, try this harder one.

A conference has 3 time slots and 5 talks. Each talk goes in exactly one slot. Talks A and B cannot be in the same slot (the speakers have a conflict). Talk C must be in an earlier slot than Talk D. Find a valid schedule.

This is harder because you have to decide what the variables represent. Some questions to think about:

Compare your encoding with your neighbor. Are they the same? If different, are both correct? How would you know?

This exercise is a reduction: you are taking a scheduling problem and turning it into constraints that a solver can answer. If your encoding captures the problem correctly, the solver gives you a valid schedule. If your encoding is wrong, the solver gives you a correct answer to the wrong question.

How This Course Works

Here are the key logistics. See the Syllabus for complete details.

Getting help:

Deadlines:

Friday is the target. Monday is the safety net.

Grading:

AI policy: You may use AI tools. Attribute what you use. Understand your work.

Collaboration: Individual work on coding assignments. Partners welcome for the mini-project (Weeks 9-10).

This Week: Reading Reflection 1

Your first deliverable is Reading Reflection 1, due this Friday.

Pick one of three readings. Spend about an hour with it. Write honestly about what you think. The readings this week are deliberately provocative: they question whether formal methods actually work. That is on purpose. We want you to form your own opinion before you have the tools to evaluate the arguments yourself.

See Reading Reflections for the submission format and grading.

Coming Up

Next Tuesday (Week 2): We go deeper into SAT: encodings, optimization, and learning from conflict. Phase C will be your first reading discussion. Here is how it works:

Come ready to argue about your reading, not just summarize it.

Coding Assignment 1: Releases this week, due Week 2 Friday. It covers material from both Lecture 1 and Lecture 2.