Example: ``Derive all even numbers up to 98''
even(0). even(Y) <- even(X), Y = X + 2, Y < 98. export even(X) query even(X) {even(0)} {even(0), even(2)} ... {even(0), ..., even(98)}Recursion: Bottom-up Evaluation
even(0). even(Y) <- even(X), Y = X + 2, Y > 0.export:even(X) would pass the safety test of the compiler, but it will start printing all integers in an infinite loop. (Use Control^C to stop it).
export even($X) will also run in the same loop, although it might not print-out anything.
Transitive Closure
|
parent(joe, jack). parent(joe, jill). parent(sam, jack). parent(jack, mary). parent(mary, lucy).Y is an ancestor of X if Y is a parent of X or if there exists a Z such that Z is a parent of X and Y is an ancestor of Z.
ancestor(X, Y) <- parent(X, Y). ancestor(X, Y) <- parent(X, Z), ancestor(Z, Y). export:ancestor(X, Y) query ancestor(X, Y)Recursion: Transitive Closure Evaluation
Step1: Start with the rule whose body is the base relation.
S1 = { ancestor(joe, jack), ancestor(joe, jill), ancestor(sam, jack), ancestor(jack, mary), ancestor(mary, lucy) }
.
Step2: Result is joined with parent. New tuples are pairs of nodes that can be reached along some path in 2 steps.
S2 ={ancestor(joe, mary),
ancestor(sam, mary), ancestor(jack, lucy)}
.
Step3: Result is joined again with parent. New tuples are pairs that are reachable along a path in 3 steps.
S3 ={ancestor(joe, jucy), ancestor(sam, lucy)}
No pairs can be reached along paths of more than 3 steps, and the computation terminates. We say that the computation has reached fixpoint.
Switching the rule order and the order of the goals within the rules
will not change the result of this transitive closure.
Recursion: Bill of Materials
|
Bill of materials (BOM) problems are related to assemblies containing superparts composed of subparts that are eventually composed of elementary parts. The assembly(Part, Subpart, Qty) predicate in the parts database contains parts, their immediate subpart, and the quantity with which they are used in the part. part_cost(BasicPart, Supplier, Cost, Time) contains the basic parts.
The following rule serves as a constraint and should be part of the specifications.
violation <- part_cost(BasicPart, _, _, _), assembly(BasicPart, _ , _).That is, a part cannot be both a basic part and a superpart within this database.
For each part find all the subparts---not just the immediate subparts
all_subparts(Part, Part). all_subparts(Part, Sub2) <- all_subparts(Part, Sub1), assembly(Sub1, Sub2).Safe query form for this rule:
export all_subparts($X, Y),For each part, basic or otherwise, find all of the basic subparts, only
export all_subparts(X, $Y),
export all_subparts($X, $Y).
Let us think bottom-up for this.
% A basic part is a subpart of itself. basic_sub_parts(BasicPart, BasicPart) <- part_cost(BasicPart, _ , _). basic_sub_parts(Part1, Sub) <- basic_sub_parts(Part, Sub), assembly(Part1, Part).For each part, basic or otherwise, find all of the basic subparts, only
Let us think bottom-up for this.
% A basic part is a subpart of itself. basic_sub_parts(BasicPart, BasicPart) <- part_cost(BasicPart, _ , _). basic_sub_parts(Part1, Sub) <- basic_sub_parts(Part, Sub), assembly(Part1, Part).