PROC [goals: RefTable, modifiabilitySpec: ModifiabilitySpec, report: ReportSpec, neededLeaves, optionalLeaves, determiningLeaves, brokenGoals: RefTable ¬
WorkOn:
--INTERNAL--
PROC [subj: Node, kind: {needed, optional, determiner}]
RETURNS [do:
BOOL ¬
FALSE] = {
a: Action ¬ NIL;
subDo: BOOL ¬ FALSE;
sourceMissing, sourcePresent, sourceNonCurrent, sourceBroken: BOOL ¬ FALSE;
missedList: NodeList ¬ NIL;
Finish:
--INTERNAL--
PROC [current: ExpensiveBool] = {
SetCurrency[subj, current];
[] ¬ nodesSeen.Insert[subj, $T];
do ¬ do OR subDo;
IF a #
NIL
THEN {
[] ¬ stackedActions.Delete[a];
IF
(
SELECT report
FROM
none => FALSE,
all => TRUE,
toBeDone => do,
ENDCASE => ERROR) AND
actionsSeen.Insert[a, $T]
THEN actions ¬ CONS[a, actions];
};
};
CheckSource:
--INTERNAL--
PROC [n: Node, which: ActionDep, optional:
BOOL] = {
CedarProcess.CheckAbort[];
InnerSetModifiability[n, goals, modifiabilitySpec];
subDo ¬ WorkOn[n, IF which=cmd THEN determiner ELSE IF optional THEN optional ELSE needed] OR subDo;
IF n.created # notExistTime THEN sourcePresent ¬ TRUE
ELSE
IF
NOT optional
THEN {
sourceMissing ¬ TRUE;
IF subj.modifiability=yes THEN missedList ¬ CONS[n, missedList];
};
SELECT n.current
FROM
true => {IF n.broken THEN SetBroken[subj, sourceBroken ¬ TRUE]};
false => sourceNonCurrent ¬ TRUE;
notComputed => ERROR;
ENDCASE => ERROR;
};
detTrue, detFalse: BOOL ¬ FALSE;
IF subj.producer = NIL THEN InnerGetProduced[subj];
IF InnerLeaf[subj]
THEN {
table: RefTable ~
SELECT kind
FROM
needed => neededLeaves,
optional => optionalLeaves,
determiner => determiningLeaves,
ENDCASE => ERROR;
IF table#NIL THEN [] ¬ table.Insert[subj, $T];
IF (NOT nodesSeen.Fetch[subj].found) OR subj.current=notComputed THEN Finish[true];
RETURN};
a ¬ subj.producer.a;
IF nodesSeen.Fetch[subj].found
THEN {
IF subj.current#notComputed
THEN {
do ¬ actionsSeen.Fetch[a].found;
RETURN;
}
ELSE a ¬ a;
};
IF
NOT stackedActions.Insert[a, $T]
THEN {
Warning[IO.PutFR1["Found cycle containing %g --- you lose", [rope[a.cmd]]]];
Abandon[]};
SetBroken[subj, subj.modifiability=yes AND subj.created=notExistTime];
InnerEnumerateSources[a, cmd, CheckSource];
IF sourceNonCurrent THEN detFalse ¬ TRUE ELSE IF sourceBroken THEN detTrue ¬ TRUE;
SELECT a.derivedFromCurrentDeterminers
FROM
TRUE => NULL;
FALSE => {
InnerRederive[a];
a.derivedFromCurrentDeterminers ¬ TRUE;
};
ENDCASE => ERROR;
sourceNonCurrent ¬ sourceBroken ¬ sourceMissing ¬ FALSE;
missedList ¬ NIL;
InnerEnumerateSources[a, data, CheckSource];
IF detFalse THEN {Finish[false]; RETURN};
IF detTrue THEN {Finish[true]; RETURN};
IF sourceNonCurrent THEN {Finish[false]; RETURN};
IF sourceBroken THEN {Finish[true]; RETURN};
IF sourceMissing
AND subj.modifiability=yes
THEN {el:
ROPE; ec:
CARDINAL;
[el, ec] ¬ EnglishList[missedList];
Warning[IO.PutFR["Can't %g because %g %g exist", [rope[a.cmd]], [rope[el]], [rope[IF ec=1 THEN "doesn't" ELSE "don't"]] ]];
SetBroken[subj, TRUE]; Finish[true]; RETURN};
IF
NOT subj.consistencyAsked
THEN {
[subj.consistent, subj.consistencyReason] ¬ a.class.CheckConsistency[a, subj];
subj.consistencyAsked ¬ TRUE;
};
IF subj.consistent THEN {InnerUnknowFails[a]; Finish[true]; RETURN};
IF sourceMissing
THEN {el:
ROPE; ec:
CARDINAL;
[el, ec] ¬ EnglishList[missedList];
Warning[IO.PutFR["Can't %g because %g %g exist", [rope[a.cmd]], [rope[el]], [rope[IF ec=1 THEN "doesn't" ELSE "don't"]] ]];
SetBroken[subj, TRUE]; Finish[true]; RETURN};
IF a.fails = true THEN {Finish[true]; RETURN};
do ¬ TRUE;
Finish[false];
};