todo-prolog/todo.pl
2024-07-08 15:48:48 +02:00

196 lines
4.2 KiB
Prolog

:- 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.