Propositional logic is limited in a very significant way: for every individual object or idea we want to describe, we have to create a new variable. We have no way of saying all objects of some type share certain properties.
We’ll introduce a few new logical constructs, and arrive at what is called first-order or predicate logic.
An constant symbol is a single object, like “my cat Tony” or “President Obama.” Note that propositional logic does not have constant symbols that represent objects; instead, propositional logic only has statements like “President Obama is a Democrat.”
We use upper-case for constant symbols: my cat Tony is
We’ll also add new relations among objects that are called
predicates. A predicate is true or false. So, the predicate
Predicates may have more than one argument:
Sometimes we want to find out for what values of, say, the second
argument of a predicate, makes the predicate true. For example, for
what values of
It turns out that when
We have the same operators as before:
We can combine variables, predicates, and relations to make statements
like “all fish have gills” and “at least one cat eats mashed
potatoes.” Two new symbols are introduced to build these statements:
For example,
Another example:
How do we know if
Now if we want to know if some statement is true, we just use the following rules:
- If the statement has a
$∀$ in front, we just check if every object makes the statement true. - If the statement has a
$∃$ in front, we just check if there is at least one object that makes the statement true.
Notice that the negation of a
Here is a very simple (and common) example of a database of first-order logic statements:
-
$(∀ m)(∀ c)(Mother(m, c) ↔ (Female(m) ∧ Parent(m, c)))$ - (mothers are female parents and vice versa)
-
$(∀ f)(∀ c)(Father(f, c) ↔ (Male(f) ∧ Parent(f, c)))$ - (fathers are male parents and vice versa)
-
$(∀ x)(Male(x) ↔ ¬ Female(x))$ - (males are not females and vice versa, and there are only two sexes; this statement recalls our discussion about the “violence” of knowledge engineering)
-
$(∀ x)(∀ y)(Brother(x, y) ↔ Brother(y, x))$ - (being a brother is a symmetric relationship)
-
$(∀ x)(∀ y)(∀ c)((Parent(x, c) ∧ Brother(x, y)) ↔ Uncle(y, c))$ - (uncles are brothers of one’s parent and vice versa)
-
$(∀ c)((∀ x)(∀ y)((Parent(x, c) ∧ BiologicalParent(y, c)) → x ≠ y) ↔ Adopted(c))$ - (adopted children all (both) of their biological parents different from their “regular” (everyday) parents)
And so on…
We also need to know about our objects and predicates. Our world is:
$\{Frank, John, Kathy, Susan, Gabrielle, Male(Frank) = T, Male(Susan) = F, …$ $BiologicalParent(John, Gabrielle) = T, Father(Frank, Gabrielle) = T, …$ $Parent(Kathy, Gabrielle) = T, BiologicalParent(Susan, Gabrielle) = T, … \}$
Let’s make a query: Is Gabrielle adopted?
First we look at the statements in the database and ask, which ones
refer to adoption? Only the last statement listed above refers to
adoption; it says that for Gabrielle to be adopted, all objects
First-order logic provides a way of writing declarative knowledge. But when we ask a query, we need some kind of procedure for determining if the query is true, or alternatively, finding objects (to put in place of the variables) to make a query true. There are several procedures that can perform this task. They are essentially all search procedures. Actually, we can apply depth-first search (say), to evaluate queries. Prolog will do this search for us, as long as we properly provide the declarative knowledge we care about.
As an example, consider the following knowledge database:
-
$(∀ x)((List(x) ∧ Empty(x)) → Sorted(x, x))$ - (an empty list is a sorted list; the
$Sorted(a, b)$ predicate means$b$ is the sorted version of$a$ )
- (an empty list is a sorted list; the
-
$(∀ x)(∀ y)(∀ z)((List(x) ∧ FirstElement(y, x) ∧ RestOfList(x, z) ∧ Empty(z)) → Sorted(x, x))$ - (a list with one element is a sorted list)
-
$(∀ x)(∀ x’)(∀ y)(∀ y’)(∀ z)(∀ z’)((List(x) ∧ Permutation(x, x’) ∧ FirstElement(y, x’)$ $∧ RestOfList(z, x’) ∧ Sorted(z, z’) ∧ FirstElement(y’, z’) ∧ LessThan(y, y’))$ $→ Sorted(x, x’))$ - (
$x’$ , a permutation of a list$x$ , is the sorted version$x$ when the first two elements of the list$x’$ are$y$ and$y’$ , and$z’$ is the sorted remainder of the list (which includes$y’$ at the front), and$y < y’$ )
- (
This is the declarative knowledge about sorted lists. The query