Upload
truongdung
View
220
Download
0
Embed Size (px)
Citation preview
What is conga?
7/28/2011
2
Grounder developed here at the University of Kentucky that implements a subset of the IDP language
Creates output for MinisatID to solve
What is IDP?
7/28/2011
3
IDP is a subset of the FO(.) logic
It extends first order logic with inductive definitions
It enforces some declaration rules for entities used within logic programs
It allows strong typing in logic programs
(and other syntactic sugar)
Which leads to…
7/28/2011
4
More readable logic programs
More manageable logic programs
(at least, in theory)
So why is this important?
It is an effective tool for describing solutions to problems
And then we let the solver, Minisat(ID), due the heavy lifting
The problems we throw at it tend to be difficult (or, at least, non-trivial) to solve, but have commonalities
Advantages?
We describe the problem, and then let a (hopefully highly!) optimized program do the model searches for us
These programs are fast; they have annual competitions for speed
And this means that we can take advantage of work done in the field optimizing these types of problems without having to re-implement complex algorithms as the state of the art is advanced
And as you’ll see, we can describe pretty interesting problems very quickly compared to using a procedural approach
So what does it actually look like?
7/28/2011
7
Input files separated into blocks
Blocks determine how declarations are interpreted
Implication and “For each/There exists” semantics
Let’s get to a simple example…
A puzzle…
Does this look familiar? ∀𝑥 ∀𝑦 ∃𝑡 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡 . ∀𝑥 ∀𝑡 ∃𝑦 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡 . ∀𝑦 ∀𝑡 ∃𝑥 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡 .
∀𝑥∀𝑦∀𝑡0∀𝑡1 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡0 ∧ 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡1
→ 𝑡0 = 𝑡1
Latin Square
Given: type int Size = {1..8} Initial(Size, Size, Size) Find: Location(Size, Size, Size) Satisfying: ! x : ! y : ? t : Location(x, y, t). ! x : ! t : ? y : Location(x, y, t). ! y : ! t : ? x : Location(x, y, t). ! x y t1 t2 : Location(x,y,t1) & Location(x,y,t2) => t1 = t2. ! x y t : Initial(x, y, t) => Location(x, y, t). Data: Initial = { }
Input files are divided into blocks
Sixish of them
Given
Declare
Find
Satisfying
Data
Maximize/Minimize
Given block
Begins with “Given:”
NOTE: Lines in the Given block are newline delimited.
No, I don’t know why they are newline delimited.
From the Latin Square problem:
Given:
type int Size = {1..8}
Given (cont’d)
The block is used to declare types, predicates (pre-determined only), and some other values.
“type int Size = {1..8}” tells us:
We have a type called Size we use in the program
It is an integer (although this only really matters if we’re doing math on it)
It has values that range from 1 to 8
Given (cont’d)
Anything in the block is treated as fixed.
We can only modify values here in the Data block (which we’ll get to much later)
But, basically, it’s just here to tell the program what types to use and what constant values to expect in the program
Declare & Find
These blocks have the same syntax.
Again, they are newline delimited
There is only one difference between the two: visibility.
Anything declared in the Declare block is known to the program, but will not be shown as part of the output
While anything in the Find block will be shown as output
Declare & Find (cont’d)
From the Latin Square problem:
Find:
Location(Size, Size, Size)
This declares (and it’s in the Find block, so it will show up on output) a predicate called Size which accepts three parameters, all of which are of the type Size.
Declare & Find (cont’d)
These blocks just declare the values
It’s still up to us to actually define them, this is what the Satisfying block is for
Satisfying
This is where the real logic happens. From our Latin Square implementation: Satisfying: ! x : ! y : ? t : Location(x, y, t). ! x : ! t : ? y : Location(x, y, t). ! y : ! t : ? x : Location(x, y, t). ! x y t0 t1 : Location(x,y,t0) & Location(x,y,t1) => t0 = t1. ! x y t : Initial(x, y, t) => Location(x, y, t).
Basic semantics
Most IDP statements are very easily translated from a standard representation of logic
But since our inputs are plain ASCII files, we don’t have fancy rotated A’s and E’s
So we make do with !’s and ?’s
A note on case…
You might have noticed by now that all predicates (relations) and types (Location, Size) start with capital letters and all quantified variables (x, y, t) start with lower case letters.
This is more than a convention, it is a requirement – predicates and types start with upper case letters, and quantified variables start with lower case letters.
Satisfying (cont’d)
Does this look familiar? ∀𝑥 ∀𝑦 ∃𝑡 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡 . ∀𝑥 ∀𝑡 ∃𝑦 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡 . ∀𝑦 ∀𝑡 ∃𝑥 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡 .
∀𝑥∀𝑦∀𝑡0∀𝑡1 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡0 ∧ 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡1
→ 𝑡0 = 𝑡1
Satisfying (cont’d)
In IDP:
! x : ! y : ? t : Location(x, y, t).
! x : ! t : ? y : Location(x, y, t).
! y : ! t : ? x : Location(x, y, t).
! x y t0 t1 : Location(x,y,t0) & Location(x,y,t1)
=> t0 = t1.
Furthermore…
Some more conversions from formal logic to IDP:
∀𝑥 ! x : (“for all x”)
∃𝑥 ? x : (“there exists at least one x”)
Which gives you
∀𝑥 ∀𝑦 ∃𝑡 𝐿𝑜𝑐𝑎𝑡𝑖𝑜𝑛 𝑥, 𝑦, 𝑡 .
“For all x, for all y, there exists at least one t such that Location(x,y,t) holds.”
! x : ! y : ? t : Location(x, y, t).
This is pretty neat.
An important line in the program…
! x y t : Initial(x, y, t) => Location(x, y, t).
Literally, “For all x, y, t, Initial(x,y,t) holding implies Location(x,y,t) holds.”
This is how we load initial state data into the problem – we define Location as a given predicate, define it in the data block
A modified program
Given: type int Size Initial(Size, Size, Size) Find: Location(Size, Size, Size) Satisfying: ! x : ! y : ? t : Location(x, y, t). ! x : ! t : ? y : Location(x, y, t). ! y : ! t : ? x : Location(x, y, t). ! x y t0 t1 : Location(x,y,t0) & Location(x,y,t1) => t0 = t1. ! x y t : Initial(x, y, t) => Location(x, y, t). Data: Size = {1..8} Initial = { 1,1,1; 1,2,2; 1,3,3; 1,4,4; 1,5,5; 1,6,6; 1,7,7; 1,8,8; }
Two things to note
“type int Size” in the Given, instead of “type int Size = {1..8}”
This lets us define Size in the data block
“Initial = { 1,1,1; 1,2,2; …”
This explicitly defines the Initial predicate as the listed tuples
Individual values separated by commas, tuples separated by semicolons, nothing exciting here.
Rules vs. Data
The Data block allows us to separate the rules and declaration from our program from the data set
This means we can have the same program easily run on multiple data sets
conga can take multiple files as input, so we can have the rules and data in separate files This is useful for your homework!
For example…
Given: type int Size Initial(Size, Size, Size) Find: Location(Size, Size, Size) Satisfying: ! x : ! y : ? t : Location(x, y, t). ! x : ! t : ? y : Location(x, y, t). ! y : ! t : ? x : Location(x, y, t). ! x y t0 t1 : Location(x,y,t0) & Location(x,y,t1) => t0 = t1. ! x y t : Initial(x, y, t) => Location(x, y, t). Data: Size = {1..8} Initial = { 1,1,1; 1,2,2; 1,3,3; 1,4,4; 1,5,5; 1,6,6; 1,7,7; 1,8,8; }
latin.cng
latin.dat
And then…
To run both of these files through conga and minisatid:
conga latin.cng latin.dat | minisatid
And, of course, you can have multiple data files working with the same rules file
(Again, this is going to be helpful for your homework…)
Some more semantics…
Sometimes, especially if you are using mathematical operators, conga will complain about being unable to find the bounds of variables
The way to get around this is explicitly declaring the type of quantified variables:
! x : ! y : ? t : Location(x, y, t).
Becomes:
! x [Size] : ! y [Size] : ? t [Size] : Location(x, y, t).
This is not needed in most cases, as conga can infer types from the statement, but using math (especially with equivalence) can confuse it
Implication vs. Equivalence
IDP supports both implication (=>) and equivalence (<=>).
It’s important to know when one or the other is needed
Equivalence, of course, is a stronger relationship
We use implication to move knowledge from our data set (the Initial predicate in the example) to our solution set (the Location predicate in the example)
But if we’re using something like a formula – where one statement defines a predicate exactly – we want to use equivalence Like, say, if we were using a predicate to test if two squares on a
chess board were diagonal to each other…