Crash course in IDP
Part 1:
predicate logic
2021-12-08
Slides by Jo Devriendt & Benjamin Callewaert
0. Sets, relations and functions
Let's quiz the homework :)
- What is a set?
- A collection of elements
- Does the order matter in a set?
- No
- What about duplicates?
- None allowed
- Given a set S with n elements, how many subsets does S have?
- 2^n (each element can either be in or out the subset)
Let's quiz the homework :)
- What is a tuple?
- A finite list of elements
- Does the order matter in a tuple?
- Yes
- What about duplicates?
- Allowed
- What is a cartesian product?
- The set of all possible tuples over some given sets.
- Given a set S with n elements, how many tuples belong to the k-fold cartesian product over S?
- n^k
- What is the 0-fold cartesian product?
- The set with exactly one element - the empty tuple: { () }
0. Sets, relations and functions
Let's quiz the homework :)
- What is a relation?
- A subset of some given cartesian product.
- Given a set S with n elements, how many relations exist over the k-fold cartesian product over S?
- 2^(n^k), as n^k is the size of the cartesian product, and 2^(n^k) is the number of subsets of the cartesian product, which is exactly the set of all relations over this cartesian product
0. Sets, relations and functions
Let's quiz the homework :)
- What is a function?
- A mapping from some set to some other
- What is its signature, arity, domain, co-domain?
- A function f with signature
has an arity k, co-domain S, and domain
- A function f with signature
- Given a set S with n elements, how many functions exist with signature ?
- n^(n^k), as n^k is the number of tuples in the domain, and we can pick any value from co-domain S for each tuple, so we can pick n values for each of the n^k tuples
0. Sets, relations and functions
- A vocabulary declares the types, predicates and functors of the specification
- Predicates and functors have an associated signature over the types
- in IDP-Z3, predicates are treated as functors to Bool
1. Vocabularies and structures in FO(.)
vocabulary People {
type Person // type
parentOf: (Person * Person) -> Bool // predicate
man: (Person) -> Bool // predicate
woman: (Person) -> Bool // predicate
brotherOf: (Person * Person) -> Bool // predicate
sisterOf: (Person * Person) -> Bool // predicate
age: (Person) -> Int // functor
eldestDaughter: () -> Person // functor
}
builtin type
constant: functor with arity 0
1. Vocabularies and structures in FO(.)
- A structure gives interpretations to symbols in the vocabulary
- type -> set (contents are called domain elements)
- predicate -> relation
- functor -> function
structure Simpsons : People {
Person := {marge, homer, lisa, bart, maggie}
parentOf := { (marge, bart), (marge, lisa), (marge, maggie),
(homer, bart), (homer, lisa), (homer, maggie) }
man := { (homer), (bart) }
woman := ??
brotherOf := ??
sisterOf := ??
age := { (homer) -> 36, (marge) -> 34, (bart) -> 10,
(lisa) -> 8, (maggie) -> 1 }
eldestDaughter := ??
}
domain element
structure Simpsons : People {
Person := {marge, homer, lisa, bart, maggie}
parentOf := { (marge, bart), (marge, lisa), (marge, maggie),
(homer, bart), (homer, lisa), (homer, maggie) }
man := { (homer), (bart) }
woman := ??
brotherOf := ??
sisterOf := ??
age := { (homer) -> 36, (marge) -> 34, (bart) -> 10,
(lisa) -> 8, (maggie) -> 1 }
eldestDaughter := ??
}
vocabulary People {
type Person // type
parentOf: (Person * Person) -> Bool // predicate
man: (Person) -> Bool // predicate
woman: (Person) -> Bool // predicate
brotherOf: (Person * Person) -> Bool // predicate
sisterOf: (Person * Person) -> Bool // predicate
age: (Person) -> Int // functor
eldestDaughter: () -> Person // functor
}
set
relation
relation
function
structure Simpsons : People {
Person := {marge, homer, lisa, bart, maggie}
parentOf := { (marge, bart), (marge, lisa), (marge, maggie),
(homer, bart), (homer, lisa), (homer, maggie) }
man := { (homer), (bart) }
woman := { (marge), (lisa), (maggie) }
brotherOf := { (bart, lisa), (bart, maggie) }
sisterOf := { (lisa, bart), (maggie, bart), (lisa, maggie),
(maggie, lisa) }
age := { (homer) -> 36, (marge) -> 34, (bart) -> 10,
(lisa) -> 8, (maggie) -> 1 }
eldestDaughter := { () -> lisa }
}
vocabulary People {
type Person // type
parentOf: (Person * Person) -> Bool // predicate
man: (Person) -> Bool // predicate
woman: (Person) -> Bool // predicate
brotherOf: (Person * Person) -> Bool // predicate
sisterOf: (Person * Person) -> Bool // predicate
age: (Person) -> Int // functor
eldestDaughter: () -> Person // functor
}
vocabulary MapCol {
type Country
type Color
border: (Country * Country) -> Bool
colorOf: (Country) -> Color
}
structure Correct : MapCol {
Country := { BE, NL, DE, LU, FR }
Color := { R, G, B, Y}
border := { (NL, BE), (NL, DE), (BE, LU),
(BE, FR), (LU, FR), (LU, DE), (DE, FR) }
colorOf := { (BE)->B, (NL)->R,
(DE)->G, (LU)->Y, (FR)->R }
}
structure Nonsense : MapCol {
Country := { BE, NL, DE, LU, FR }
Color := { R, G, B, Y}
border := { (BE, BE), (FR, NL) }
colorOf := { (BE)->R, (NL)->R, (DE)->R, (LU)->R, (FR)->R }
}
??
2. Terms and atoms
maggie
eldestDaughter()
age(eldestDaughter())
- A term is either
- a domain element
- a constant
- an application of a functor to the right amount and type of terms
2. Terms and atoms
- An atom is either
- an equality between two terms
- a disequality between two terms
- an application of a predicate to the right amount and type of terms
eldestDaughter() = maggie
maggie ~= eldestDaughter()
age(eldestDaughter()) ~= 0
brotherOf(eldestDaughter(), bart)
NOTE: FO(.) is typed!
age(0) = maggie
2. Terms and atoms
vocabulary People {
type Person := {homer, marge, bart, lisa, maggie}
parentOf: (Person * Person) -> Bool // predicate
man: (Person) -> Bool // predicate
woman: (Person) -> Bool // predicate
brotherOf: (Person * Person) -> Bool // predicate
sisterOf: (Person * Person) -> Bool // predicate
age: (Person) -> Int // functor
eldestDaughter: () -> Person // functor
}
homer
man
0 ~= 1
bart = brotherOf(lisa)
parentOf(marge, eldestDaughter())
age(lisa) = eldestDaughter()
age(eldestDaughter())
age(age(age(age(lisa))))
age(bart) ~= age(eldestDaughter())
sisterOf(eldestDaughter(),bart)
eldestDaughter()
parentOf(bart, eldestDaughter())
term, atom or bug?
term (domain element)
bug: predicate without input
atom, maps to true/false (0 and 1 ar domain elements of builtIn type Int)
bug, brotherOf takes 2 arguments
atom (false in above structure, but that does not matter)
bug, eldestDaughter() maps to Person, age maps to Int
term, maps to Int
bug, age maps to Int and takes Person as input, so can not be applied to itself
atom
atom
term
atom (correct predicate)
2. Terms and atoms
A structure is a "possible world". Terms and atoms are statements which can be evaluated in a structure. This evaluation under a structure is (again) called an interpretation.
Informally, a structure is a solution, interpretations are values, and predicates & functors are variables. Statements such as terms, atoms, formulas have a derived value.
2. Terms and atoms
- A term is either
- a domain element
- a constant
- an application of a functor to the right amount and type of terms
Given a structure U, the interpretation of
- a domain element is itself
- a constant C() is C's interpretation in U
- a functor application f(t1, ..., tk) is the value obtained by applying the interpretation of f in U to the interpretation of (t1, ..., tk) in U
maggie
eldestDaughter()
age(eldestDaughter())
age := {(homer) -> 36,
(marge) -> 34,
(bart) -> 10,
(lisa) -> 8,
(maggie) -> 1}
eldestDaughter :=
{() -> lisa}
Interpretations of terms are always domain elements of some type
2. Terms and atoms
Given a structure U, the interpretation of
- an equality is true iff both terms have the same interpretation
- a disequality is true iff both terms have a different interpretation
- a predicate application p(t1, ..., tk) is true iff the interpretation of (t1, ..., tk) in U is an element of the interpretation of p in U
- An atom is either
- an equality between two terms
- a disequality between two terms
- an application of a predicate to the right amount and type of terms
eldestDaughter() = maggie
maggie ~= eldestDaughter()
age(eldestDaughter()) ~= 0
brotherOf(eldestDaughter(), bart)
Interpretations of atoms are truth values:
true or false
2. Terms and atoms
structure Simpsons : People {
Person := {marge, homer, lisa, bart, maggie}
parentOf := { (marge, bart), (marge, lisa), (marge, maggie),
(homer, bart), (homer, lisa), (homer, maggie) }
man := { (homer), (bart) }
woman := { (marge), (lisa), (maggie) }
brotherOf := { (bart, lisa), (bart, maggie) }
sisterOf := { (lisa, bart), (maggie, bart), (lisa, maggie),
(maggie, lisa) }
age := { (homer) -> 36, (marge) -> 34, (bart) -> 10,
(lisa) -> 8, (maggie) -> 1 }
eldestDaughter := { () -> lisa }
}
eldestDaughter() = maggie
maggie ~= eldestDaughter()
age(eldestDaughter()) ~= 0
brotherOf(eldestDaughter(), bart)
false
true
true
false
2. Terms and atoms
homer
0 ~= 1
eldestDaughter()
brotherOf(bart,lisa)
age(eldestDaughter())
age(bart) ~= age(eldestDaughter())
parentOf(bart, eldestDaughter())
if not bug, what is interpretation in Simpsons?
term: homer (interpretation odomain element is itself)
atom: true
term: lisa
atom: true
term: 8
atom: true
atom: false
3. Quantor-free formulas
brotherOf(eldestDaughter(), bart)
~brotherOf(eldestDaughter(), bart)
~brotherOf(eldestDaughter(), bart) & bart ~= eldestDaughter()
brotherOf(eldestDaughter(), bart) | bart ~= eldestDaughter()
eldestDaughter()=lisa => woman(eldestDaughter())
eldestDaughter()=lisa <=> woman(eldestDaughter())
A QF formula is either
- an atom
- a negation of a formula
- a conjunction of two formulae
- a disjunction of two formulae
- an implication of two formulae
- an equivalence of two formulae
Order of operations:
3. Quantor-free formulas
A QF formula is either
- an atom
- a negation of a formula
- a conjunction of two formulae
- a disjunction of two formulae
- an implication of two formulae
- an equivalence of two formulae
Given a structure U, the interpretation of
- negation = "not"
- conjunction = "and"
- disjunction = "or"
- implication = "if ... then ..."
- equivalence is true iff both formula have the same interpretation
Tricky!
P | Q | P => Q |
---|---|---|
false | false | true |
false | true | true |
true | false | false |
true | true | true |
P | Q | P <=> Q |
---|---|---|
false | false | true |
false | true | false |
true | false | false |
true | true | true |
Truth table
3. Quantor-free formulas
rain() | cloudy() | rain() => cloudy() |
---|---|---|
false | false | true |
false | true | true |
true | false | false |
true | true | true |
rain() => cloudy()
"If it rains, then it is cloudy."
This is still true even if there are clouds but no rain!
3. Quantor-free formulas
rain() | cloudy() | ~rain() | cloudy() |
---|---|---|
false | false | true |
false | true | true |
true | false | false |
true | true | true |
rain() => cloudy()
"If it rains, then it is cloudy."
Note that the implication is equivalent to the following disjunction:
~rain() | cloudy()
3. Quantor-free formulas
Logical Equivalence: Two formulas F and G are logically equivalent F ≡ G if the truth values of both formulas F and G are always the same.
- (P ∧ Q) ≡ (Q ∧ P) and (P ∨ Q) ≡ (Q ∨ P) (commutativity)
- ((P ∧ Q) ∧ R) ≡ (P ∧ (Q ∧ R)) and ((P ∨ Q) ∨ R) ≡ (P ∨ (Q ∨ R)) (associativity)
- ¬(¬P) ≡ P (double negation)
-
(P ⇒ Q) ≡ (¬Q ⇒ ¬P) (contraposition)
- (P ⇒ Q) ≡ (¬P ∨ Q)
- (P ⇔ Q) ≡ ((P ⇒ Q) ∧ (Q ⇒ P))
- ¬(P ∧ Q) ≡ (¬P ∨ ¬Q) and ¬(P ∨ Q) ≡ (¬P ∧ ¬Q)
- (P ∧ (Q ∨ R)) ≡ ((P ∧ Q) ∨ (P ∧ R)) (distributivity of ∧ over ∨)
- (P ∨ (Q ∧ R)) ≡ ((P ∨ Q) ∧ (P ∨ R)) (distributivity of ∨ over ∧)
3. Quantor-free formulas
- (P ∧ Q) ≡ (Q ∧ P)
- ((P ∨ Q) ∨ R) ≡ (P ∨ (Q ∨ R))
- ¬(¬P) ≡ P
- (P ⇒ Q) ≡ (¬Q ⇒ ¬P)
- (P ⇒ Q) ≡ (¬P ∨ Q)
- (P ⇔ Q) ≡ ((P ⇒ Q) ∧ (Q ⇒ P))
- ¬(P ∧ Q) ≡ (¬P ∨ ¬Q)
- (P ∧ (Q ∨ R)) ≡ ((P ∧ Q) ∨ (P ∧ R))
Same meaning - equivalent
Same meaning - equivalent
Same meaning - equivalent
Verify via truth tables
3. Quantor-free formulas
age(eldestDaughter())~=10
sisterOf(eldestDaughter(),lisa)
man(homer) | woman(homer)
sisterOf(bart,maggie) | (brotherOf(bart,lisa) & brotherOf(bart,marge))
woman(homer) <=> ~man(homer)
age(eldestDaughter())=10 <=> age(bart)=10
age(eldestDaughter())=10 => age(bart)=10
age(eldestDaughter())=8 => age(bart)=10 & age(maggie)=1
What is the interpretation of the following QF formulas?
structure Simpsons : People {
Person := {marge, homer, lisa, bart, maggie}
parentOf := { (marge, bart), (marge, lisa), (marge, maggie),
(homer, bart), (homer, lisa), (homer, maggie) }
man := { (homer), (bart) }
woman := { (marge), (lisa), (maggie) }
brotherOf := { (bart, lisa), (bart, maggie) }
sisterOf := { (lisa, bart), (maggie, bart), (lisa, maggie),
(maggie, lisa) }
age := { (homer) -> 36, (marge) -> 34, (bart) -> 10,
(lisa) -> 8, (maggie) -> 1 }
eldestDaughter := { () -> lisa }
}
true
false
true
false
true
false
true
true
3. Quantor-free formulas
age(eldestDaughter())~=10
sisterOf(eldestDaughter(),lisa)
man(homer) | woman(homer)
sisterOf(bart,maggie) | (brotherOf(bart,lisa) & brotherOf(bart,marge))
woman(homer) <=> ~man(homer)
age(eldestDaughter())=10 <=> age(bart)=10
age(eldestDaughter())=10 => age(bart)=10
age(eldestDaughter())=8 => age(bart)=10 & age(maggie)=1
What is the interpretation of the following QF formulas?
Are these brackets necessary?
Order of operations:
~ > & > | > =>/<= > <=>
3. Quantor-free formulas
age(eldestDaughter())~=10
sisterOf(eldestDaughter(),lisa)
man(homer) | woman(homer)
sisterOf(bart,maggie) | (brotherOf(bart,lisa) & brotherOf(bart,marge))
woman(homer) <=> ~man(homer)
age(eldestDaughter())=10 <=> age(bart)=10
age(eldestDaughter())=10 => age(bart)=10
age(eldestDaughter())=8 => age(bart)=10 & age(maggie)=1
structure Simpsons : People {
Person := {homer, marge, bart, lisa, maggie}
parentOf := ??
man := ??
woman := ??
brotherOf := ??
sisterOf := ??
age := ??
eldestDaughter := ??
}
Given the above formulas, complete the following structure with interpretations such that all of the formulas are true:
4. Formulas with quantors
Each introduces a variable ranging over some type:
Quantors allow statements over a range of elements at the same time. There are two basic quantors:
These variables can be used as terms in a subsequent formula:
4. Formulas with quantors
forall is true iff the subsequent formula is true for all domain elements in the range.
exists is true iff the subsequent formula is true for at least one domain element in the range.
Interpretations of formulas are truth values:
true or false
In IDP, 'forall' is written as '!' and 'exists' is written as '?'.
forall can be seen as a "big and" (conjunction) over its range
exists can be seen as a "big or" (disjunction) over its range
! x in Person: ~man(x) | ~woman(x)
(~man(homer) | ~woman(homer))
& (~man(marge) | ~woman(marge))
& (~man(bart) | ~woman(bart))
& (~man(lisa) | ~woman(lisa))
& (~man(maggie) | ~woman(maggie))
is equivalent to
? x in Person: ~(man(x) | woman(x))
~(man(homer) | woman(homer))
| ~(man(marge) | woman(marge))
| ~(man(bart) | woman(bart))
| ~(man(lisa) | woman(lisa))
| ~(man(maggie) | woman(maggie))
is equivalent to
This is a good approximation of how IDP handles quantors internally
4. Formulas with quantors
! x in Person: ~man(x) | ~woman(x)
? x in Person: ~(man(x) | woman(x))
! x in Person: ? y in Person: parentOf(y,x)
! x in Person: (? y in Person: sisterOf(x,y)) => woman(x)
What is the interpretation of these formulas?
structure Simpsons : People {
Person := {marge, homer, lisa, bart, maggie}
parentOf := { (marge, bart), (marge, lisa), (marge, maggie),
(homer, bart), (homer, lisa), (homer, maggie) }
man := { (homer), (bart) }
woman := { (marge), (lisa), (maggie) }
brotherOf := { (bart, lisa), (bart, maggie) }
sisterOf := { (lisa, bart), (maggie, bart), (lisa, maggie),
(maggie, lisa) }
age := { (homer) -> 36, (marge) -> 34, (bart) -> 10,
(lisa) -> 8, (maggie) -> 1 }
eldestDaughter := { () -> lisa }
}
true
false
true
false
4. Formulas with quantors
! x in Country: ! y in Country: border(x,y) => colorOf(x)~=colorOf(y)
Truth value of below formula in either structure?
structure Correct : MapCol {
Country := { BE, NL, DE, LU, FR }
Color := { R, G, B, Y}
border := { (NL, BE), (NL, DE), (BE, LU),
(BE, FR), (LU, FR), (LU, DE), (DE, FR) }
colorOf := { (BE)->B, (NL)->R,
(DE)->G, (LU)->Y, (FR)->R }
}
structure Nonsense : MapCol {
Country := { BE, NL, DE, LU, FR }
Color := { R, G, B, Y}
border := { (BE, BE), (FR, NL) }
colorOf := { (BE)->R, (NL)->R, (DE)->R, (LU)->R, (FR)->R }
}
4. Formulas with quantors
Homework I
age(eldestDaughter())~=10
sisterOf(eldestDaughter(),lisa)
man(homer) | woman(homer)
sisterOf(bart,maggie) | (brotherOf(bart,lisa) & brotherOf(bart,marge))
woman(homer) <=> ~man(homer)
age(eldestDaughter())=10 <=> age(bart)=10
age(eldestDaughter())=10 => age(bart)=10
age(eldestDaughter())=8 => age(bart)=10 & age(maggie)=1
- Adapt the Simpsons structure so that it makes all of the above true.
- Why does there not exist a single structure that makes all of the above false?
- Truth value of below formulas:
Crash course in IDP
Part 2:
extensions of predicate logic
2021-12-15
5. Some IDP specifics
! x in Person: ~man(x) | ~woman(x).
? x in Person: ~(man(x) | woman(x)).
! x in Person: ? y in Person: parentOf(y,x).
! x in Person: (? y in Person: sisterOf(x,y)) => woman(x).
All constraints end with '.'
Shows where the constraint (and quantors inside it) end.
To use domain elements in formula, type interpretation must be given in vocabularium:
vocabulary People {
type Person := {homer, marge, bart, lisa, maggie}
parentOf: (Person * Person) -> Bool // predicate
man: (Person) -> Bool // predicate
woman: (Person) -> Bool // predicate
brotherOf: (Person * Person) -> Bool // predicate
sisterOf: (Person * Person) -> Bool // predicate
age: (Person) -> Int // functor
eldestDaughter: () -> Person // functor
}
6. Cardinality aggregate
-
Counts the number of true formulas for given range
- introduces variable, similar to quantor
- Is a term: evaluates to Int
- can be used wherever one would use an Int term
#{x in Person : ~(man(x) | woman(x))} = 0.
"the number of persons that are not man or woman is zero"
E.g.:
#{x in Person : ~(man(x) | woman(x))}
"count"
range with variable x
subformula
! x in Person : man(x) | woman(x).
Equivalently:
7. If-then-else
- Switches the value of a term based on a condition
- Is a term: evaluates to some non-fixed type
- can be used wherever one would use a term of that type
- "=>" is an atom that evaluates to true/false
Score(CInsert) = (if Insert() then 3 else 0).
"the score of CInsert is 3 if we have an insert, else it is 0"
E.g.:
if Insert() then 3 else 0
case if true
condition
case if false
Insert() => Score(CInsert) = 3.
~Insert() => Score(CInsert) = 0.
Equivalently:
7. If-then-else
- Switches the value of a term based on a condition
- Is a term: evaluates to some non-fixed type
- can be used wherever one would use a term of that type
- "=>" is an atom that evaluates to true/false
if Insert() then 3 else 0
case if true
condition
case if false
If-then-else allow a simple way to encode (first-hit) decision tables. Can you see how?
8. Arithmetic
With the use of mathematical symbols we can construct more complex numerical terms
Given two terms t1, t2, the following are valid numerical terms:
- t1 + t2 (addition)
- t1 - t2 (subtraction)
- - t1 (unary subtraction)
- t1 / t2 (division)
- t1 * t2 (multiplication)
- t1 % t2 (modulus)
- abs(t1) (absolute value)
Given two terms t1, t2, the following are valid numerical atoms:
- t1 = t2 (equality)
- t1 ~= t2 (disequality)
- t1 < t2 (less than)
- t1 =< t2 (less than or equal)
- t1 > t2 (greater than)
- t1 >= t2 (greater than or equal)
Watch out! => and <= are implications, not inequalities!
8. Arithmetic
age(eldestDaughter()) = age(Bart)-2.
2*age(Bart) = age(eldestDaughter()).
age(eldestDaughter()) % 3 = 2.
! x, y in Person: parentOf(x,y) => age(x) > age(y)+18.
! x, y in Person: parentOf(x,y) => age(y) > age(x)+18.
What is the truth value of the following formulas?
structure Simpsons : People {
Person := {marge, homer, lisa, bart, maggie}
parentOf := { (marge, bart), (marge, lisa), (marge, maggie),
(homer, bart), (homer, lisa), (homer, maggie) }
man := { (homer), (bart) }
woman := { (marge), (lisa), (maggie) }
brotherOf := { (bart, lisa), (bart, maggie) }
sisterOf := { (lisa, bart), (maggie, bart), (lisa, maggie),
(maggie, lisa) }
age := { (homer) -> 36, (marge) -> 34, (bart) -> 10,
(lisa) -> 8, (maggie) -> 1 }
eldestDaughter := { () -> lisa }
}
true
false
true
false
true
8. Arithmetic
A "forall" is a "big and" over a range.
A "exists" is a "big or" over a range.
A "sum aggregate" / "sum lambda" is a "big sum" over a range.
condition ("filters" range)
value ("maps" to numeric value)
sum aggregate - old syntax
sum{x in Person : man(x) : age(x)} < 100.
sum(lambda x in Person: if man(x) then age(x) else 0) < 100.
sum lambda - new syntax
9. Definitions
- If-then-else allow to define functors
- for all inputs, determine the output of the functor
- (Inductive) definitions allow to define predicates
{
! x in Person: sick(x) <- hasFever(x).
! x in Person: sick(x) <- hasRunnyNose(x) & coughing(x).
}
"A person will be sick if they have a fever or if the have both a runny nose and are coughing. In all other cases, they will not be sick."
Rules covering different cases
If no rule applies, the defined symbol is false.
9. Definitions
- If-then-else allow to define functors
- for all inputs, determine the output of the functor
- (Inductive) definitions allow to define predicates
{
! x in Person: sick(x) <- hasFever(x).
! x in Person: sick(x) <- hasRunnyNose(x) & coughing(x).
}
"A person will be sick if they have a fever or if the have both a runny nose and are coughing. In all other cases, they will not be sick."
! x in Person: hasFever(x) => sick(x).
! x in Person: hasRunnyNose(x) & coughing(x) => sick(x).
! x in Person: sick(x) <=> hasFever(x).
! x in Person: sick(x) <=> hasRunnyNose(x) & coughing(x).
In what situations (structures!) are the below different?
- If-then-else allow to define functors
- for all inputs, determine the output of the functor
- (Inductive) definitions allow to define predicates
{
! x in Person: sick(x) <- hasFever(x).
! x in Person: sick(x) <- hasRunnyNose(x) & coughing(x).
}
"A person will be sick if they have a fever or if the have both a runny nose and are coughing. In all other cases, they will not be sick."
! x in Person: sick(x) <=> hasFever(x) | (hasRunnyNose(x) & coughing(x)).
Equivalently:
9. Definitions
- If-then-else allow to define functors
- for all inputs, determine the output of the functor
- (Inductive) definitions allow to define predicates
{
! x in Person: sick(x) <- hasFever(x).
! x in Person: sick(x) <- hasRunnyNose(x) & coughing(x).
}
head of rule
body of rule with description of a case
arrow '<-' denoting a rule
defined predicate
forall quantification over the type of the predicate
brackets show which rules belong together
9. Definitions
- Has "well-founded" semantics
- Allows expression of recursive / inductive concepts
{
! x in City: reachable(x) <- x = kontich.
! x in City: reachable(x) <- ? y in City: reachable(y) & rail(x,y).
}
This is what's being defined!
induction step
base case
No equivalent non-definition formula exists in predicate logic
9. Definitions
10. Other extensions
// range notation for type interpretation
type ExRes := {0..3}
// functor interpretation with "else"
TmaxT := { (Fluoroloy_A02) -> 150} else 200
// sum via lambda
TotalCost() = sum(lambda c in component : Score(c) + Cost(Material(c))).
// quantification over predicate
? (x,y) in rangemap_CostIndex_CostIndex: x < Quantity() =< y.
// builtin truth values
true.
false.
- And more, see docs.idp-z3.be/en/stable/IDPLanguage.html
- When in doubt, ask expert at KU Leuven
- they have a responsibility to teach the language
11. The hard part: writing your own constraints
Let's try three examples in the interactive consultant:
interactive-consultant.idp-z3.be
- graph coloring
- nqueens
- sudoku
vocabulary V {
type Country
type Color
border: (Country * Country) -> Bool
colorOf: (Country) -> Color
}
theory T : V {
// two countries with a border should have a different color
// ...
}
structure S : V {
Country := { BE, NL, DE, LU, FR }
Color := { R, G, B, Y}
border := { (NL, BE), (NL, DE), (BE, LU),
(BE, FR), (LU, FR), (LU, DE), (DE, FR) }
}
Known interpretation
No known interpretation: this is what we want to solve
"Two countries with a border should have a different color."
This is a statement about all ('!') pairs (two variables: x,y) of countries:
11. The hard part: writing your own constraints
! x in Country: ! y in Country: ... something about x, y ...
! x in Country: ! y in Country: border(x,y) => ... something ...
What do we know about these two countries? That if they have a border, then something must be true:
What must be true? The color of the countries should be different:
! x in Country: ! y in Country: border(x,y) => colorOf(x) ~= colorOf(y).
vocabulary V {
type Index := {1..4}
type Diag := {1..7}
n : () -> Index
toDiag1: (Index * Index) -> Diag
toDiag2: (Index * Index) -> Diag
queen: (Index * Index) -> Bool
}
structure S : V {
n := 4
}
theory T : V {
! x, y in Index: toDiag1(x, y) = x - y + n().
! x, y in Index: toDiag2(x, y) = x + y - 1.
// every row has exactly one queen
// every column has exactly one queen
// every diagonal has at most one queen
}
"Every row has exactly one queen."
This is a statement about every ('!') row (one variable: x):
! x in Index: ... something about x ...
"has ... queen" -> queens reside on squares, which are combinations of rows and columns. We already introduced a row (it's 'x'), now we need to express something about a column 'y'.
! x in Index: ... y in Index ... something about x and y...
"exactly one" suggests a cardinality aggregate to introduce y.
! x in Index: #{y in Index: ... something about x and y ... } = 1.
Now we have: for each row x, there exists exactly one column y.
... where there is a queen!
! x in Index: #{y in Index: queen(x,y) } = 1.
vocabulary V {
type Row := {1..4} // The rows of the grid (1 to 4)
type Column := {1..4} // The columns of the grid (1 to 4)
type Block := {1..4} // 4 blocks of 2x2 where the numbers need to be entered
type Number := {1..4} // The numbers of the grid (1 to 4)
blockOf: (Row * Column) -> Block
// This declares the block of each cell.
// This means that blockOf(r,c)=b if and only if
// b is the block of the cell on row r and column c.
solution: (Row * Column) -> Number
// The solution: a number assigned to every cell.
// A cell is represented by its row and column.
// For example: solution(1,2) = 3 means that the
// cell on row 1 and column 2 contains a 3.
}
theory T : V {
// On every row every number is present.
// In every column every number is present.
// In every block every number is present.
}
structure S : V {
// Fix which cells lie in which block
blockOf := {(1,1)->1, (1,2)->1, (2,1)->1, (2,2)->1,
(3,1)->2, (3,2)->2, (4,1)->2, (4,2)->2,
(1,3)->3, (1,4)->3, (2,3)->3, (2,4)->3,
(3,3)->4, (3,4)->4, (4,3)->4, (4,4)->4}
}
Homework II: truth value of below formulas
! x in Person: !y in Person: brotherOf(x,y) => sisterOf(y,x).
! x in Person: !y in Person: brotherOf(x,y) <= sisterOf(y,x).
! x in Person: #{y in Person: parentOf(y,x)} < 2.
? x in Person: ! y in Person: ! z in Person: parentOf(y,x) & parentOf(z,x) => y=z.
true
false
false
true
Crash course in IDP
Part 3:
modeling full problem domains
2021-12-22
Contents
- Have a look at the homeworks
- A handful of slides on modeling advise
- Improve omniseal and lipseal specifications
- Assignment on modeling a simple problem domain
- Feedback: what one thing would you prefer to change the most for this crash course?
12. The very hard part: deciding vocabulary of a problem domain
- Vocabulary introduces symbols for the concepts, objects, relationships, functions... in the problem domain
- A good vocabulary leads to simple and readable formulas
- picking the right vocabulary is hard!
- "refactor" the vocabulary + formulas when needed
13. Modeling advise
- Always start small!
- as in programming, extending what works is easier than figuring out why a huge program does not work
- Use a complete but small solution to quickly check the formulas as you write them.
- (partly) avoids writing formulas that are too strict.
- Use IDP-Z3 to generate solutions after adding formulas. Check that these solutions make sense given the formulas you wrote so far.
- (partly) avoids writing formulas that are insufficiently strict.
13. Modeling advise
- Size of specification can be measured in two ways
- number of ground symbols
- the number of symbols in the interactive consultant
- number of ground constraints
- the number of constraints where all ranges are "replaced by their possible values"
- number of ground symbols
- Larger size => slower solving time
13. Modeling advise
- Some formulas represent constraints, others definitions
- definitions give meaning to intermediary symbols, constraints restrict set of solutions
- definitions can typically be substituted by their defining formula in the constraints
- useful to know the difference
sick() => takeMedicine().
tax() < 10000.
sick() <=> hasFever() | (hasRunnyNose() & coughing()).
tax() = (if income()<limit() then 0 else income()*0.4).
(if income()<limit() then 0 else income()*0.4) < 10000.
(hasFever() | (hasRunnyNose() & coughing())) => takeMedicine().
13. Modeling advise
- forall ! works best with implication => or disjunction |
- exists ? works best with conjunction &
- equivalence <=> mainly used in combination with forall ! to express definitions
"only people above 18 should drink alcohol"
! x in People: drinksalcohol(x) => age(x)>=18.
"there is someone over 18 who does not drink alcohol"
? x in People: age(x)>=18 & ~drinksalcohol(x).
"adults are those people older than 18"
! x in People: adult(x) <=> age(x)>=18.
"nobody is both a man and a woman"
! x in People: ~(man(x) & woman(x)).
"there exists someone who is neither man nor woman"
? x in People: ~(man(x) | woman(x)).
"nonbinary people are those who identify neither as man nor as woman"
! x in People: nonbinary(x) <=> ~(man(x) | woman(x)).
13. Modeling advise
Always start small!
Homework III: modeling from scratch
In this exercise we’ll try to model a simple scheduling problem. A company has five tasks that need to be executed: task1, task2, task3, task4 and task5. To do this the company has 6 employees: bart, ben, jo, deise, andrea and joost. But every employee is able to complete certain tasks. Bart can complete task1. Ben can complete task1 and task2. Jo can complete task2 and task4. Andrea can complete task1, task2, and taks3. Deise can complete task 3 and task5. And finally, Joost can complete all tasks. The aim of the company is to minimize the total salary cost. Only employees that execute a task get paid. The salary of the employees is very different. Bart earns 20 euro. Ben earns 30 euro, Jo gets 50 euro, Andrea gets 100 euro, Deise 120 euro and Joost 150 euro. Finally, there are a couple of constraints:
-
Every task needs to be executed.
-
An employee can only execute a task if he can complete it.
-
An employee can only work on 1 task.
The ultimate goal of the company is to minimize the total salary that needs to be paid.
Task
-
Create a vocabulary that can represent this problem. Think about when to use a predicate or a function, which types will be needed, etc …
-
Make a structure using this vocabulary that incorporates the info from the story above (bart earns 20 euros, Andrea can complete task1, task2, and task3, …)
-
Complete the structure with an arbitrary solution to test your constraints (written in the next step) .
-
Make sure that all constraints are satisfied by writing a good theory.
-
Find a solution that minimizes the total wage cost
TODO: incorporate feedback
- The jump from "evaluate these formulas" to "solve nqueens / sudoku" is too big.
- add intermediary examples, perhaps some without quantification
- explain that for cardinality, {x in T1: x in T2: ... } is written as {x in T1 , x in T2: ... } (for the nqueens diagonal constraint)
- Give some technique to translate English sentences to FO(.). E.g., look for quantors, what is being said about these quantors, use appropriate connectives ("=>" and "|" for "!", "&" for "?"). Incorporate modeling advise in that section. Probably flesh this out as a separate workshop.
Crash course IDP
By krr
Crash course IDP
- 881