Reasoning ¶
This section provides several illustrative reasoning examples using the LNN. Each problem consists of the natural language description of the background knowledge and the query. The logical representations of the background knowledge and query follows in First-order Logic. Finally, code snippets showing the direct mapping to the LNN representation are provided. There are examples typically found in the theorem proving literature. The goal is to prove that the background knowledge entails the query.
The problems can be parsed into First-order Logic using any semantic parsing modules.
The output of semantic parsing is facts and rules.
We extract
predicates
,
constants
(or
objects
)
and logical connectives (→, ∀, etc.).
Facts are made of
predicates
and
constants
. Here, we manually
parse each text into FOL to illustrative theorem proving.
Simple Geometry reasoning example ¶
The first example shows how to apply theorem proving, and LNN in particular, on a simple geometric example. The background knowledge contains some general rules about shapes of objects, and facts about some given objects. The goal is to prove geometrical properties of existing objects.
Problem in Natural Language ¶
Background knowledge:
All
square
objects are
rectangular
.
All
rectangular
objects have
four sides
.
The object
c
is a
square
. The object
k
is a
square
.
Query: Is there any object with four sides ?
We extract the following predicates:
Square
,
Rectangle
and
Fourside
; and two objects
(constants):
c
and
k
.
Problem in First-order Logic ¶
Background knowledge
Square(c)
Square(k)
∀x
Square(x)
→
Rectangle(x)
∀x
Rectangle(x)
→
Fourside(x)
Query
∃x
Fourside(x)
?
LNN Code ¶
Since the LNN has a one-to-one mapping with First-order Logic, the problem can be directly translated to the LNN representation. The following code snippet shows how to build an LNN model for the above problem and performance inference to answer queries.
from lnn import (Predicate, Variable,
Exists, Implies, Forall, Model, Fact, World)
model = Model()
# Variablle
x = Variable('x')
# Predicate declarations
square = Predicate('square')
rectangle = Predicate('rectangle')
foursides = Predicate('foursides')
# Axioms declarations
square_rect = Forall(x, Implies(square(x), rectangle(x)))
rect_foursides = Forall(x, Implies(rectangle(x), foursides(x)))
# Query
query = Exists(x, foursides(x))
# Add predicates and rules to the model
model.add_knowledge(square, rectangle, square_rect, rect_foursides, query)
# Add facts to the model
model.add_data({square: {'c': Fact.TRUE, 'k': Fact.TRUE}})
# Perform inference
steps, facts_inferred = model.infer()
# Inspect the query node
print(model['foursided_objects'].true_groundings)
Expected output:
{'c',
'k'}
More complex reasoning example ¶
Problem in Natural Language ¶
Background knowledge:
The law says that it is a
crime
for an
American
to
sell
weapons
to
hostile
nations.
The
country
Nono
, an
enemy
of
America
, and other countries
Gotham
and
Wakanda
all have some
missiles
.
Nono
’s
missiles
were
sold
to it by
Colonel
West
, who is
American
.
Query:
Prove that
Colonel
West
is a
criminal
.
We manually extract the following predicates:
Owns
,
Missile
,
American
,
Enemy
,
Weapon
,
Sells
, and
Hostile
; and the following objects:
nono
,
m1
,
m2
,
m3
,
west
and
america
. Below is the problem in FOL.
Problem in First-order Logic ¶
Owns(nono,m1)
Missile(m1)
Missile(m2)
Missile(m3)
American(west)
Enemy(nono,america)
Enemy(wakanda,america)
Enemy(gotham,america)
∀ x,y,z
American(x)
∧
Weapon(y)
∧
Sells(x,y,z)
∧
Hostile(z)
→
Criminal(x)
∀ x
Missile(x)
∧
Owns(nono,x)
→
Sells(west,x,nono)
∀ x
Missile(x)
→
Weapon(x)
∀ x
Enemy(x,america)
→
Hostile(x)
LNN Code ¶
The code snippet below shows the declaration of the model and all the predicates.
from lnn import (Predicate, Variable, Join, And,
Exists, Implies, Forall, Model, Fact, World)
model = Model() # Instantiate a model.
x, y, z, w = map(Variable, ['x', 'y', 'z', 'w'])
# Define and add predicates to the model.
owns = model['owns'] = Predicate('owns', 2) # binary predicate
missile = model['missile'] = Predicate('missile')
american = model['american'] = Predicate('american')
enemy = model['enemy'] = Predicate('enemy', 2)
hostile = model['hostile'] = Predicate('hostile')
criminal = model['criminal'] = Predicate('criminal')
weapon = model['weapon'] = Predicate('weapon')
sells = model['sells'] = Predicate('sells', 3) # ternary predicate
The code snippet below shows an example of adding the background knowledge into the model. All the other rules can be added to the model similarly.
# Define and add the background knowledge to the model.
america_enemies = (
Forall(x, Implies(enemy(x, (y, 'America')),
hostile(x),
),
world=World.AXIOM)
)
model.add_knowledge(america_enemies)
The code snippet below shows how to add the query into the model.
# Define queries
query = Exists(x, criminal(x))
model.add_knowledge(query)
Finally, we can add facts into the model.
# Add facts to model.
model.set_facts({
owns: {('Nono', 'M1'): Fact.TRUE},
missile: {'M1': Fact.TRUE},
american: {'West': Fact.TRUE},
enemy: {('Nono', 'America'): Fact.TRUE},
})
Then we are ready to perform inference and answer queries (aka theorem proving):
model.infer()
print(model[query].true_groundings)
Expected output:
{west}
.