/* Rule interpreter for counting reductions */ :- op(40,xfy,&). :- op(30,xf,is_true). solve(A,1) :- fact(A). solve(A,N) :- rule(A,B,Name), solve_body(B,NB), N is NB+1. solve_body(A&B,N) :- solve_body(A,NA), solve_body(B,NB), N is NA+NB. solve_body(A is_true,N) :- solve(A,N). % Sample rule base rule(oven(Dish,top),pastry(Dish) is_true & size(Dish,small) is_true,place1). rule(oven(Dish,middle),pastry(Dish) is_true & size(Dish,big) is_true,place2). rule(oven(Dish,middle),main_meal(Dish) is_true,place3). rule(oven(Dish,bottom),slow_cooker(Dish) is_true,place4). rule(pastry(Dish),type(Dish,cake) is_true,pastry1). rule(pastry(Dish),type(Dish,bread) is_true,pastry2). rule(main_meal(Dish),type(Dish,meat) is_true,main_meal). rule(slow_cooker(Dish),type(Dish,milk_pudding) is_true,slow_cooker). should_fold(solve(oven(D,P),N),oven(D,P,N)). should_fold(solve(pastry(D),N),pastry(D,N)). should_fold(solve(main_meal(D),N),main_meal(D,N)). should_fold(solve(slow_cooker(D),N),slow_cooker(D,N)). should_fold(solve(type(D,P),N),type(D,P,N)). should_fold(solve(size(D,P),N),size(D,P,N)). should_unfold(solve_body(G,N)). should_unfold(rule(A,B,Name)). program(rule_interpreter,[(solve(A1,1) :- fact(A1)), (solve(A2,N) :- rule(A2,B,Name), solve_body(B,NB), N is NB+1)]). % Program 18.5: Specializing a rule interpreter