CSE 505: Computing with Logic
Fall 2020
Homework #3
Due: Oct 19
Homework 3 is on Satisfiability Checking and Applications.
Part I: Preparation
For this part, we will work with formulas in propositional logic
written in three different styles, and on Prolog predicates to
convert formulas written in one style to another.
- Readable form:
Propositions in this form are Prolog atoms (e.g. p1,
temp, x, etc.).
Formulae, represented by φ can be
- Propositions
- Constructed from other formulas using unary connective
"\+" (negation) and binary connectives
"," (conjunction),
";" (disjunction),
"=>" (implication) and
"<=>" (equivalence).
We use the connecties in the usual infix form, using parenthesis
to group operations, and, in the absence of parantheses, following the
standard convention that the negation operator has the highest
precedence, the binary operators are all left associative, with
conjunction having higher precedence over implication and
equivalence, which, in turn have higher precedence over
disjunction.
All the above syntactic criteria can be easily satisfied by
representing the formulae as Prolog terms, and by using the
following declaration to specify the precedence and associativity
of the implication/equivalence operators :
:- op(1050, xfy, (=>)).
:- op(1050, xfy, (<=>)).
- CNF form:
In this form, we use the same propositions as the Readable form,
but each formula is
- A list of clauses, where
- A list of literals, where
- Each literal is a proposition, or negation of a
proposition (e.g. \+ p)
Semantically, each clause represents a disjunction of its literals,
and each formula is a conjunction of its clauses.
- Simplified DIMACS form:
Most SAT solvers use this format for formulae, specified as a text
file. In this form, the propositions are numbered from 1..M.
Positive literals are represented by that proposition's number,
while negative literals are represented by the corresponding
negative number. Formulas are written in CNF using a special
notation, as explained below.
The first line of the file has:
p cnf M N
("p" and "cnf" have to appear as is.)
Here, "M" is an integer representing the number of
distinct propositions in the formula, and "N" as an
integer representing the number of clauses in the formula.
The remaining lines of the file represent clauses of the formula,
each clause appearing in a single line.
The literals in the clause are listed on that line (separated by a
space). End of clause is marked by "0" (note that "0" does not
represent a proposition).
The entire file is taken as a formula in conjunctive normal form.
For instance, the formula in readable form as (q => r), (r,s =>
q) may be represented as
p cnf 3 2
-1 2 0
-2 -3 1 0
(Here q,r,s are propositions 1,2,3 respectively).
Part I: Questions
Define predicates described below in a single Prolog file:
- Binary predicate toCNF that, given a formula
in Readable form as the first argument, returns its equivalent CNF
in the second argument.
For example, toCNF( ((q => r), (r,s => q)), Q)
may return Q=[[\+ q, r], [\+ r, \+ s, q]] (order of
literals in clauses, or order of clauses in formula may differ).
Assume the first argument is in valid readable form, no need to
take any special measures to check it.
- 4-ary predicate toDimacs that, given a formula
in CNF form as its first argument, returns its equivalent Dimacs
form in its remaining three arguments as follows:
- The second argument will be the number of distinct
propositions in the formula
- The third argument will be the number of clauses in the
formula, and
- The fourth argument will be the clauses themselves.
For example, toDimacs([[\+ q, r], [\+ r, \+ s, q]], M, N,
Cl) will return M=3, N=2, and
Cl = [[-1, 2], [-2, -3, 1]]
- Unary predicate prop2dimacs that takes a single file
name, fn, as an argument, such that fn.prop
contains a set of propositional formulae in readable form. Each
formula in the .prop file will end with a period (".").
prop2dimacs then writes to fn.cnf the
equivalent formula in Dimacs form (including the header, trailing
0s in clauses, etc.). The output .cnf file should be
in a form that can input to SAT solvers like minisat, picosat, etc.
Part II: Planning as Satisfiability
This second part is more open-ended, and may use the predicates you
defined in Part I.
Background:
Automated Planning is an important and very actively-studied area of AI. One
of the more accessible parts of this area, and the one immediately
close to propositional satisfiability, is STRIPS-Style
Planning.
STRIPS-Style planning is done in a setting where world states are
described as a set of conditions. We can move from one world
state to another by taking one of many
available actions. At each step only one
action is taken. In this style of
planning, we consider only deterministic actions: the result of an
action takes us to a specific state. The set of all actions is
completely specified.
Each action, act, is specified by
- precondition, pre(act): a set of conditions (or their negations)
that must hold,
- positive-postcondition, post-add(act): a set of
conditions that will hold in the destination state (i.e., enabled
by this action; and
- negative-postcondition, post-delete(act): a set of conditions that will not
hold in the destination state (i.e. disabled by this action).
A planning problem specification also provides
- Init: a set of conditions that characterizes the
initial state; and
- Goal: a set of conditions that characterize goal
states.
The problem then is to find a sequence of actions that
will take us from the initial state to a goal state.
There are a number of explanatory resources in the Web
for STRIPS-Style planning (e.g. on Wikipedia). Instead of repeating those, we'll give a short
illustrative example from Blocks World.
Blocks World Example
Specific planning problems in STRIPS-Style planning are called
"Planning Domains". Within each domain, there are many
instances that differ in the number of objects
in the world (hence the number of conditions), initial state and/or goals states.
Blocks world consists of a number of same-sized wooden blocks that
can be stacked on top of each other. Each block can be placed directly on
a table (which is large enough to hold all the blocks), or on another
(unique) block. Each block may have another (unique) block on top
of it, or may be clear.
World states can be specified using the following family of
conditions:
- on(b1, b2): Block b1 is on
block b2.
- clear(b1): Block b1 is clear: has nothing
on top.
- on_table(b1): Block b1 is directly on the
table.
The picture below shows a specific state (say, at Step 1):
This state can be described by the set of conditions:
on_table(b), on_table(a), on(c, a), clear(b), clear(c)
There are 3 types of actions:
Action | Pre | Post-Add | Post-Del |
move_table_to_block(X, Z)
Move block X from table to top of block Z: |
clear(X), on_table(X), clear(Z) |
on(X, Z) |
on_table(X), clear(Z) |
move_block_to_table(X, Y)
Move block X from top of block Y to table: |
clear(X), on(X, Y) |
on_table(X), clear(Y) |
on(X, Y) |
move_block_to_block(X, Y, Z)
Move block X from top of block Y to top of block Z: |
clear(A), on(Z, Y), clear(Z) |
on(X, Z), clear(Y) |
on(X, Y), clear(Z) |
From the state pictured above, we can move block c to
top of block b (all preconditions are satisfied). Taking
this action will result in state (at Step 2):
on_table(b), on_table(a), on(c, b), clear(a), clear(c)
The only things left to specify for this planning problem are the
initial state and the goal states:
For example, the initial state could be
Init = on_table(a), on(b,c), on(c,a), clear(b)
The goal state could be characterized by:
Goal = on(a,c)
Note the above specification of goal states characterizes multiple
states depending on the placement of block B.
Satisfiability:
Note a plan takes us from an initial state to a goal state in a
sequence of steps. We consider the problem of determining
whether or not there is a plan taking MaxSteps steps or fewer.
We can formulate this problem in terms of satisfiability
checking.
Note also that the conditions that hold at one state may not
hold at a different state. However, the satisfiability problem
takes a propositional formula as an input, a formula whose form or
meaning does not change over time!
To model the planning problem to satisfiability, we have to invent
"static" propositions, which themselves do not change
over time, but together capture the dynamic behavior of the
planning world's conditions. The key is to embed the "step
number".
Important: Since we are given MaxSteps, the "step number" will be between 0 and MaxSteps.
We can introduce two families of propositions:
- action(Act, i): Action Act was taken at
step i.
- holds(Cond, i): Condition Cond (from the
planning problem) holds at step i.
First of all, it is best to think of action and
holds as sets of propositions, with whatever appears in the
parentheses as subscripts. Secondly, note that Act and
Cond range over a finite set, and i is an integer in
range 0..MaxSteps.
Thirdly, observe that in example above, condition clear(b) holds
at Step 1, but does not hold at Step 2. This "dynamic" behavior
can be captured with our propositions since
holds(clear(b), 1) is true, but
holds(clear(b), 2) is not. The truth value of the
"holds" family of propositions themselves do not change over
time.
Now, we can map the planning problem to a SAT instance by figuring
out how the "holds" and "action" family of propositions are
related to each other via the planning problem specification.
State:
A state is defined by the set of conditions (and their
negations) that hold at that state.
A condition C holds at a step I if
- I=0, initial state: if C is in Init
- I>0, a subsequent state:
The let A be some action such that action(A, I-1) is
true (that is, A was the last action taken). Then, it must
be either
- C is in post-add(A) (enabled by this action)
- C held at step I-1, and C is not in
post-del(A)) (i.e., not disabled by this action).
So, given which actions are taken at each step, we know how to
relate the truth values of the "holds" family of propositions.
holds(C, 0) iff C ∈ Init
holds(C, I), I>0 iff action(A, I-1) and
(C ∈ post-add(A) or
(holds(C, I-1) iff C ∉ post-del(A)))
|
Note the use of "If and only if" in the above; that's because
there is no other way for holds(C,I) to be true.
Action:
This is a bit trickier. Note that when preconditions of an
action hold, that action can be selected. But it does not mean
that the action must be taken. So the encoding of which action
is to be taken at a given step needs to be looked at
differently.
Say, an action act was taken at step i. Then,
clearly, its preconditions must have been true at the previous state. So,
- If action A was chosen
at step i, and if P is a precondition of
A, then P must hold at i.
action(A, I) and C ∈ pre(A) implies holds(C, I)
|
Only one action can be taken in any step, so we have
- It is not possible for actions A and B
(distinct actions) to be chosen at the same step i.
not(action(A, I) and action(B, I) and A ≠ B)
|
Part II: Your Task
Given a planning instance Inst for the blocks world domain
described above, generate a Dimacs CNF file F encoding a
propositional formula such that a SAT solver, with F
as input, will say "satisfiable" if and only of the planning
instance has a valid solution.
Planning Instance Description:
Each planning instance will be in a separate file,
consisting of the following definitions:
- blocks(list). where list
is a Prolog list of all the blocks in the instance.
For instance,
blocks([a,b,c]).
- init(list). where list
is a Prolog list of conditions characterizing the initial
state of the instance. For instance,
init([on(c,b), on(b,a), on_table(a), clear(c)]).
- goal(list). where list
is a Prolog list of conditions characterizing the goal
states of the instance. For instance,
goal([on(a,c), clear(b)]).
- maxstep(n) where n is
a positive (non-zero) integer.
Part III: Extra Work, Extra Credit
Having solved Part II, consider now a generalization to the
blocks world domain, known as the "Bounded-table blocks
world domain":
- There are N locations on the table where
blocks can be kept.
- Each location can have at most one block directly on it.
- Each stack of blocks can have at most 2 blocks.
- Each problem instance has at most 2(N-1) blocks.
This section is completely open ended: you can choose the
set of conditions for this problem, and how instances should
be specified.
Write a Prolog program to generate a propositional formula
in a Dimacs CNF file, that can then be checked for
satisfiability using standard SAT solvers. Again,
satisfiability must mean plan existence and vice versa.
Grading:
Parts I and II total 15 points each (5 points each for the 3
questions in Part I). You can get 10 extra points for
successfully completing Part III.
Submission:
Submit your solution to Part I of the homework as
a single Prolog file via BlackBoard.
For parts II and III, you can set up private git
repositories and share its handle with me. Or send me a
zip/tar archive via email.
Last modified: Tue Oct 6 23:31:47 EDT 2020