Original JavaScript Exercise 4.79 Beginning with the data base and the rules you formulated in exercise 4.73, devise a rule for adding greats to a grandson relationship. This should enable the system to deduce that Irad is the great-grandson of Adam, or that Jabal and Jubal are the great-great-great-great-great-grandsons of Adam. (Hint: Represent the fact about Irad, for example, as ((great grandson) Adam Irad). Write rules that determine if a list ends in the word grandson. Use this to express a rule that allows one to derive the relationship ((great . ?rel) ?x ?y), where ?rel is a list ending in grandson.) Check your rules on queries such as ((great grandson) ?g ?ggs) and (?relationship Adam Irad). There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in Github. Exercise 4.80 Let us modify the data base and the rules of exercise 4.73 to add great to a grandson relationship. This should enable the system to deduce that Irad is the great-grandson of Adam, or that Jabal and Jubal are the great-great-great-great-great-grandsons of Adam. Change the assertions in the data base such that there is only one kind of relationship information, namely related. The first item then describes the relationship. Thus, instead of son("Adam", "Cain"), you would write related("son", "Adam", "Cain"). Represent the fact about Irad, for example, as related(list("great", "grandson"), "Adam", "Irad") Write rules that determine if a list ends in the word "grandson". Use this to express a rule that allows one to derive the relationship list(pair("great", $rel),$x, $y) where$rel is a list ending in "grandson". Check your rules on the queries related(list("great", "grandson"), $g,$ggs) and related($relationship, "Adam", "Irad"). This exercise is a bit more verbose than the original, because of the choice of using explicit predicate symbols rather than general lists, see comment in the beginning of section 4.4.1. So the hint here is to revert to a list representation that makes the relationship explicit, and therefore programmable. This trick is used in the implementation of HiLog, a logic programming language with first-class predicates, see Chen, Weidong; Kifer, Michael; Warren, David S. (February 1993). HiLog: A foundation for higher-order logic programming. Journal of Logic Programming. 15 (3): 187–230. There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in Github. [1] That a particular method of inference is legitimate is not a trivial assertion. One must prove that if one starts with true premises, only true conclusions can be derived. The method of inference represented by rule applications is modus ponens, the familiar method of inference that says that if A is true and A implies B is true, then we may conclude that B is true. [2] We must qualify this statement by agreeing that, in speaking of the inference accomplished by a logic program, we assume that the computation terminates. Unfortunately, even this qualified statement is false for our implementation of the query language (and also false for programs in Prolog and most other current logic programming languages) because of our use of not and lisp-value. javascript_predicate. As we will describe below, the not implemented in the query language is not always consistent with the not of mathematical logic, and lisp-value javascript_predicate introduces additional complications. We could implement a language consistent with mathematical logic by simply removing not and lisp-value javascript_predicate from the language and agreeing to write programs using only simple queries, and, and or. However, this would greatly restrict the expressive power of the language. One of the major concerns of research in logic programming was to find ways to achieve more consistency with mathematical logic without unduly sacrificing expressive power. [3] This is not a problem of the logic but one of the procedural interpretation of the logic provided by our interpreter. We could write an interpreter that would not fall into a loop here. For example, we could enumerate all the proofs derivable from our assertions and our rules in a breadth-first rather than a depth-first order. However, such a system makes it more difficult to take advantage of the order of deductions in our programs. One attempt to build sophisticated control into such a program is described in de Kleer et al. 1977. Another technique, which does not lead to such serious control problems, is to put in special knowledge, such as detectors for particular kinds of loops (exercise 4.77). However, there can be no general scheme for reliably preventing a system from going down infinite paths in performing deductions. Imagine a diabolical rule of the form To show$P(x)$is true, show that$P(f(x))$is true, for some suitably chosen function$f\$.
[4] Consider the query (not (baseball-fan (Bitdiddle Ben))). not(baseball_fan(list("Bitdiddle", "Ben"))). The system finds that (baseball-fan (Bitdiddle Ben)) baseball_fan(list("Bitdiddle", "Ben")) is not in the data base, so the empty frame does not satisfy the pattern and is not filtered out of the initial stream of frames. The result of the query is thus the empty frame, which is used to instantiate the input query to produce (not (baseball-fan (Bitdiddle Ben)))not(baseball_fan(list("Bitdiddle", "Ben"))).
[5] A discussion and justification of this treatment of not can be found in the article Negation as Failure by Clark (1978).
4.4.3   Is Logic Programming Mathematical Logic?