:-dynamic(fired/1). :-dynamic(stopped/0). :-dynamic(current_list/1). go:- retractall(current_list(_)), retractall(stopped), assert(current_list([5,3,2,4,1])), current_list(X), write('Initial state: '), write(X), nl, run_rules. run_rules:- \+(stopped),!, conflict_set(CList), choose_rule(CList,Rule), fire_rule(Rule), run_rules. run_rules. conflict_set(CList):- findall(R, belongs_to_c_set(R), CList). belongs_to_c_set(rule(N, Cond, Act)):- rule(N, Cond, Act), satisfy(Cond). fire_rule(rule(N, Cond, Act)):- call(Act),!. choose_rule([R|Ignore], R). rule(1,[left_of(A,B),left_of(B,C),bigger_than(A,C)], swap(A,C)). rule(2,[left_of(A,B),bigger_than(A,B)], swap(A,B)). rule(3,[no_left_of_and_bigger],stop). satisfy(Conditions):- satisfy_each(Conditions),!. satisfy_each([]). satisfy_each([H|T]):- call(H), satisfy_each(T). left_of(A,B):- current_list(L), split(L,A,[B|_]). bigger_than(A,B):- A>B. no_left_of_and_bigger:- \+(some_left_of_and_bigger). some_left_of_and_bigger:- left_of(A,B), bigger_than(A,B). swap(A,B):- retract(current_list(L)), list_with_swap(L,A,B,New), assert(current_list(New)), write('Swap performed: '), write(New),nl. stop:- assert(stopped). list_with_swap([],_,_,[]). list_with_swap([A|T],A,B,[B|T1]):- list_with_swap(T,A,B,T1). list_with_swap([B|T],A,B,[A|T1]):- list_with_swap(T,A,B,T1). list_with_swap([H|T],A,B,[H|T1]):- \+(H=A),\+(H=B), list_with_swap(T,A,B,T1). split([H|T],H,T). split([H|T],A,List):- split(T,A,List).