I have a question. I am trying to understand First Order Logic, so I found this code:
# Import libraries
import aima.utils
import aima.logic
# The main entry point for this module
def main():
# Create an array to hold clauses
clauses = []
# Add first-order logic clauses (rules and fact)
clauses.append(aima.utils.expr("(American(x) & Weapon(y) & Sells(x, y, z) & Hostile(z)) ==> Criminal(x)"))
clauses.append(aima.utils.expr("Enemy(Nono, America)"))
clauses.append(aima.utils.expr("Owns(Nono, M1)"))
clauses.append(aima.utils.expr("Missile(M1)"))
clauses.append(aima.utils.expr("(Missile(x) & Owns(Nono, x)) ==> Sells(West, x, Nono)"))
clauses.append(aima.utils.expr("American(West)"))
clauses.append(aima.utils.expr("Missile(x) ==> Weapon(x)"))
# Create a first-order logic knowledge base (KB) with clauses
KB = aima.logic.FolKB(clauses)
# Add rules and facts with tell
KB.tell(aima.utils.expr('Enemy(Coco, America)'))
KB.tell(aima.utils.expr('Enemy(Jojo, America)'))
KB.tell(aima.utils.expr("Enemy(x, America) ==> Hostile(x)"))
# Get information from the knowledge base with ask
hostile = aima.logic.fol_fc_ask(KB, aima.utils.expr('Hostile(x)'))
criminal = aima.logic.fol_fc_ask(KB, aima.utils.expr('Criminal(x)'))
# Print answers
print('Hostile?')
print(list(hostile))
print('\nCriminal?')
print(list(criminal))
print()
# Tell python to run main method
if __name__ == "__main__": main()
Now I don't understand 1 thing:
When do I use this: clauses.append(aima.utils.expr()
and when do I use this: KB.tell(aima.utils.expr()
Both are facts, but I don't really understand why you have to set some facts differently. Here is the link to the forum: https://www.annytab.com/first-order-logic-in-python/?unapproved=2276&moderation-hash=66a786c6e08ac109543a3518a62ea729#comment-2276
Please let me know!
As far as I can see, you first create a list of clauses in the clause
array. This you then use to initialise the knowledge base KB
.
With the tell()
method, you can add further expressions/clauses to the knowledge base.
In principle they are equivalent, in that both ways of doing this result in clauses being added to the knowledge base, only some at initialisation, others afterwards.
You might have a particular setting/domain which is fixed, and different expressions for different problems, so you can put all the common expressions in at the beginning, and add others later during processing.