/* Explanation-Based Generalization (EBG) in Picat v3. This is a port of the program minihyper.pl in I. Bratko, "Prolog Programming for Artificial Intelligence", 4th edn., Pearson Education / Addison-Wesley 2012 Page 621ff (Figures 25.6, 25.7) This is the lift movement example from figure 25.6. Note: I redefined 'A =:= ' to eq(A,B) This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import ebg_v3. main => go. go ?=> load_lift_movement, Goal = $go(3,6,Moves), GenGoal = $go(Level1,Level2,GenMoves), ebg(Goal,GenGoal,Condition), bp.asserta($(GenGoal :- Condition)), number_vars([Level1,Level2,GenMoves]), println([level1=Level1,level2=Level2]), println(goal=Goal), println(genGoal=GenGoal), println(condition=Condition), println(moves=Moves), nl, % fail, aleternative solutions (1+1+1+1-1) etc) nl. go => true. go2 ?=> go, Goal = $go(7,10,Moves), GenGoal = $go(Level1,Level2,GenMoves), ebg(Goal,GenGoal,Condition), bp.asserta($(GenGoal :- Condition)), number_vars([Level1,Level2,GenMoves]), println([level1=Level1,level2=Level2]), println(goal=Goal), println(genGoal=GenGoal), println(condition=Condition), println(moves=Moves), nl. go2 => true. % Figure 25.6 Two problem definitions for explanation-based generalization. load_lift_movement :- bp.assertz($(go(Level, GoalLevel, Moves) :- move_list( Moves, Distance), % (Distance =:= GoalLevel - Level))), eq(Distance,GoalLevel - Level))), % hakank bp.assertz($(move_list( [], 0))), bp.assertz($(move_list( [Move1 | Moves], Distance + Distance1) :- move_list( Moves, Distance), move( Move1, Distance1))), bp.assertz($(move(up, 1))), bp.assertz($(move(down, -1))). eq(A,B) :- A =:= B. %% go( Level, GoalLevel, Moves) if %% list of moves Moves brings lift from Level to GoalLevel %% % go(Level, GoalLevel, Moves) :- % move_list( Moves, Distance), % % Distance =:= GoalLevel - Level. % eq(Distance, GoalLevel - Level). % % move_list( [], 0). % move_list( [Move1 | Moves], Distance + Distance1) :- % move_list( Moves, Distance), % move( Move1, Distance1). % move( up, 1). % move( down, -1). % operational( A == B) :- println($operational(A,B)). operational( eq(A, B)). % hakank