:- dynamic task/2. :- dynamic requires/2. :- dynamic idx/2. :- discontiguous load/0. all_tasks(L):- findall(X, task(X, _), L). all_tasks(L, STATE):- findall(X, task(X, STATE), L). print_task(X):- task(X,ISDONE), write(ISDONE), write(': '), write(X). print_task_list([],_). print_task_list([H|T],N) :- M is N+1, retractall(idx(N, _)), asserta(idx(N, H)), write(N), write(". "), print_task(H), nl, print_task_list(T, M). list_all :- all_tasks(L), print_task_list(L,1). list_all :- all_tasks(L), print_task_list(L,1). list :- all_tasks(L, todo), print_task_list(L,1). list_done :- all_tasks(L, done), print_task_list(L,1). print_list([]). print_list([H|T]) :- write(H),nl, print_list(T). new(X) :- task(X, todo), write("task already exist"), !. new(X) :- asserta(task(X, todo)), write("added task "), write(X). new(X,Y) :- idx(Y, Task), new(X, Task). new(X,Y) :- asserta(task(X, todo)), asserta(requires(X, Y)), uncheck(X), write("added task "), write(X), write(" as a subtask for "), write(X). delete(X):- idx(X,Y), delete(Y). delete(X):- retractall(task(X,_)), retractall(requires(X,_)), retractall(requires(_,X)). delete(X,Y):- idx(X,T), delete(T,Y). delete(X,Y):- idx(Y,T), delete(X,T). delete(X,Y):- retractall(requires(X,Y)). depend(X,Y) :- idx(X, Task), depend(Task, Y). depend(X,Y) :- idx(Y, Task), depend(X, Task). depend(X,Y) :- task(X, todo), task(Y, _), asserta(requires(X, Y)). depend(X,Y) :- task(X, done), task(Y, todo), uncheck(X). depend(X,Y) :- task(X, done), task(Y, done). check(X) :- idx(X, Task), check(Task). check(X) :- task(X, todo), \+ (requires(Y, X), task(Y,todo)), asserta(task(X, done)), retractall(task(X, todo)), write("marked "), write(X), write(" as done"), !. check(X) :- task(X, todo), (requires(Y, X), task(Y,todo)), write("you need to do "), write(Y), write(" before doing "), write(X), !. check(X) :- task(X, done), write("the task is already done "), !. check(X) :- \+ task(X, todo), write("no such task as "), write(X). indent(0). indent(N):- write(" "), M is N-1, indent(M). tree_branch([],_). tree_branch([X|T],N):- indent(N), print_task(X), nl, findall(Y, requires(Y,X), L), M is N+1, tree_branch(L,M), tree_branch(T,N). tree(X):- task(X,_), tree_branch([X],0). tree(X):- idx(X,Y), tree(Y). uncheck(X) :- idx(X, Task), uncheck(Task). uncheck(X):- task(X, done), retractall(task(X, done)), asserta(task(X, todo)), write("unchecked task: "), write(X), nl, findall(Parent, requires(X, Parent), L), uncheck_list(L). uncheck_list([]). uncheck_list([H|T]):- task(H, todo), uncheck_list(T). uncheck_list([H|T]):- uncheck(H), uncheck_list(T). save_requirement(T1, T2, Stream) :- requires(T1, T2), write_canonical(Stream, requires(T1,T2)), write(Stream, '.\n'). save_requirement_list(T2, [T1], Stream) :- save_requirement(T1, T2, Stream). save_requirement_list(T2,[H|T], Stream) :- save_requirement(H, T2, Stream), save_requirement_list(T2, T, Stream). save_task_requirements(Task, Stream) :- findall(X, requires(X, Task), L), save_requirement_list(Task, L, Stream). save_task_requirements(Task, _) :- \+ requires(_, Task). save_task(Task, Stream) :- task(Task, State), write_canonical(Stream, task(Task, State)), write(Stream, '.\n'), save_task_requirements(Task, Stream). save_task_list([Task], Stream) :- save_task(Task, Stream). save_task_list([H|T], Stream) :- save_task(H, Stream), save_task_list(T, Stream). save :- all_tasks(L), open('data.pl', write, Stream), save_task_list(L, Stream), close(Stream). load_task(Stream) :- read(Stream, Task), Task \= end_of_file, % write("reading: "), % write(Task), % nl, asserta(Task), load_task(Stream). load_task(Stream) :- read(Stream, Task), Task = end_of_file, % write("reading last: "), % write(Task), close(Stream). load :- open('data.pl', read, Stream), load_task(Stream). clear :- retractall(task(_, _)). load.