ttss:-
    see('$ttss/advice'),seen,!,
    cleanslate,!,
    initiate,!,
    ruleinterpret.

initiate:-
    print('This is the Trainee Teacher Support System'),nl,nl,
    problemwithclass.

ruleinterpret:-
    (recorded(data,[advicegiven,true],REF1),
     conclude;
     stalemate).

ruleinterpret:-
    inference,!,
    metainference,!,
    ruleinterpret.

conclude:-
    print('Thank you for consulting the Trainee Teacher Support System').

inference:-
    control,!,
    generate,!,
    investigate,!,
    resolution.

control:-
    printgoals,!,
    nl,
    print('Current goals:-'),nl,
    foreach(recorded(goal,X,_), (nl,print(X),nl)),!,nl,
    print('Suspended goals:-'),nl,
    foreach(recorded(suspended,Y,_),(nl,print(Y),nl)),!.

control.

metainference:-
    reason,!,
    rationalise,!,
    metaresolution.

generate:-
    clearout,!,
    update.

clearout:-
    foreach(recorded(current,[G,V,_],REF1),
            (recorded(goal,[G,V],_);
             erase(REF1))).

update:-
    foreach(recorded(goal,[G,V],_),
            (recorded(current,[G,V,_],_);
             foreach(recorded(G,[V,r,c,RULE],_),
                     (recorda(current,[G,V,RULE],REF1),
                      evaluate(RULE))))).


/*
marker(neg).
*/

evaluate(RULE):-
    antecedent(RULE,A),!,
    collectdata(A).
/*
    collectdata(A)              ,(retract(marker(pos)),print(RULE),assert(marker(neg)); marker(neg)) .
*/

antecedent([A|C],A).

collectdata([]).

collectdata([[D,_]|ANTES]):-
    lookup(D),!,
    collectdata(ANTES).

lookup(D):-
    recorded(data,[D,_],_);
    question(D);
/*
    (   question(D)                     ,   changemarker)      ;
*/
    recorda(data,[D,unknown],REF1).


changemarker:-
    retract(marker(_)),
    assert(marker(pos)).






question(D):-
    D.

investigate:-
    foreach(recorded(current,[_,_,RULE],_),
            (confirm(RULE),
             recorda(cfs,RULE,REF1))).

confirm(RULE):-
    antecedent(RULE,A),!,
    verify(A).

verify([]).

verify([[D,V]|ANTES]):-
    recorded(data,[D,V],_),!,
    verify(ANTES).

resolution:-
    foreach(recorded(cfs,RULE,REF1),
            (recordinfer(RULE,CONS),
             effect(CONS),
             erase(REF1))).

recordinfer(RULE,[C|ONS]):-
    antecedent(RULE,ANTES),!,
    consequent(RULE,[C|ONS]),!,
    link(ANTES,C).

link([],_).

link([A|NTES],C):-
    recorda(inferbase,[C,A],REF),
    link(NTES,C).

effect([]).

effect([C|ONS]):-
    modifyrecords(C),!,
    assertcons(C),!,
    effect(ONS).

modifyrecords(CONS):-
    modifygoal(CONS).

modifygoal([D,V]):-
    foreach(recorded(goal,[D,_],REF1),
            erase(REF1)).

assertcons([D,V]):-
    recorded(data,[D,V],_);
    foreach(recorded(data,[D,unknown],REF1),
            erase(REF1)),!,
    recorda(data,[D,V],REF2).

reason:-
    metaclearout,!,
    metaupdate.

metaclearout:-
    foreach(recorded(metacurrent,[D,V,_],REF1),
            (recorded(data,[D,V],REF2);
             erase(REF1))).

metaupdate:-
    foreach(recorded(data,[D,V],_),
            (recorded(metacurrent,[D,V,_],_);
             foreach(recorded(D,[V,mr,a,RULE],_),
                     (recorda(metacurrent,[D,V,RULE],_),
                                evaluate(RULE))))).

rationalise:-
    foreach(recorded(discovering,X,REF1),
            erase(REF1)),!,
    foreach(recorded(metacurrent,[D,V,RULE],_),
            (notapplic(D,V);
             confirm(RULE),
             recorda(mcfs,RULE,_))).

notapplic(D,unknown):-
    (recorded(discovering,D,_);
     recorda(discovering,D,_)),!,
    not(recorded(goal,[D,_],_)),!,
    not(recorded(suspended,[D,_],_)).

metaresolution:-
    foreach(recorded(mcfs,RULE,REF1),
            (consequent(RULE,CONS),
             execute(CONS),
             erase(REF1))).

consequent([A|C],CONS):-
    liststrip(C,CONS).

liststrip([CONS],CONS).

execute([]).

execute([C|ONS]):-
    (suspend(C);
     assertgoal(C),!,
    execute(ONS)).

suspend([D,V]):-
    recorded(discovering,D,_),!,
    recorded(metacurrent,[D,unknown,RULE],_),
    consequent(RULE,CONS),
    currentgoal(CONS),!,
    assertsusgoal([D,V]).

currentgoal(CONS):-
    member(GOAL,CONS),
    (recorded(goal,GOAL,_);
     recorded(suspended,GOAL,_)).

assertsusgoal([D,V]):-
    foreach(recorded(goal,[D,V],REF1),
    erase(REF1)),!,
    (recorded(data,[D,true],_);
     recorded(data,[D,false],_);
     recorded(suspended,[D,V],_);
     recorda(suspended,[D,V],REF2)).

assertgoal([D,V]):-
    foreach(recorded(suspended,[D,V],REF1),
            erase(REF1)),!,
    (recorded(data,[D,true],_);
     recorded(data,[D,false],_);
     recorded(goal,[D,V],_);
     recorda(goal,[D,V],REF2)).





menu([C|HOICES],VALUE):-
    nl,nl,!,
    print(C),nl,nl,nl,!,
    show(HOICES),!,
    obtain(HOICES,VALUE).

show([]):-
    nl,nl.

show([C|HOICES]):-
    setout(C),nl,!,
    show(HOICES).

setout([LETTER,TEXT,_]):-
    print(LETTER),tab(2),!,
    print(TEXT).

obtain(CHOICES,VALUE):-
    interpret(ANS),!,
    findvalue(ANS,CHOICES,VALUE).

interpret(ANS):-
    get(LETTER),!,
    name(ANS,[LETTER]).

findvalue(ANS,[],_):-
    sortoutanswer(ANS).

findvalue(ANS,[C|HOICES],VALUE):-
    answer(ANS,C,VALUE);
    findvalue(ANS,HOICES,VALUE).

answer(ANS,[ANS,_,VALUE],VALUE).





do(A):- A, !.

foreach(P,A):-
        P,
        do(A),
        fail.

foreach(P,A).

findlist(L,X,P):-
        asserta(findlistis([])),
        foreach(P,(     retract(findlistis(M)),
                        asserta(findlistis([X|M]))    )   ),
        retract(findlistis(L)),!.
