add(Fact) :- true(Fact), !. /* If the fact being added is */ /* already known to be true, */ /* then do nothing. */ add(Fact) :- /* Otherwise, */ assert(true(Fact)), /* put the fact into the */ write('Adding: '), /* database, tell the user */ write(Fact), nl, /* that you have done so, and */ find_new_consequences(Fact). /* work out the consequences */ /* of this new fact. */ find_new_consequences(Fact) :- /* To compute consequences, */ rule(Head, Body), /* for each rule in the base, */ select(Fact, Body, Remainder), /* see if the fact matches */ /* something in the body of */ /* rule, and work out the bits*/ /* it doesn't match too, then */ all_facts(Remainder), /* if all the bits it doesn't */ /* match are facts, then */ add(Head), /* add the head of this rule */ /* to the base. */ fail. /* Then backtrack to find */ /* other rules. */ find_new_consequences(Fact). /* This clause stops the */ /* failure-driven loop. */ /* select matches a fact */ /* against a list of facts & */ /* returns the remainder. */ select(Fact, [Fact], true). /* If there is an exact match */ /* then remainder is `true'. */ select(Fact, [Fact | Facts], Facts). /* If the fact matches the */ /* head, then remainder is */ /* the tail. */ select(Fact1, [Fact2 | Facts1], [Fact2 | Facts2]) :- /* Else, */ select(Fact1, Facts1, Facts2). /* we recurse down the list*/ all_facts([Fact | Facts]) :- /* All the facts in a list are*/ true(Fact), /* true if the head is true */ all_facts(Facts). /* and those in the tail are. */ all_facts([]). /* Simple case. */ true(true). /* Extra fact that true is true*/ go :- /* Top-level routine that reads*/ read(Fact), /* in facts and calls the */ add(Fact), /* inferencing system */ go. /* repeatedly. */