PROC [goals: RefTable, modifiabilitySpec: ModifiabilitySpec, report: ReportSpec]
WorkOn:
--INTERNAL--
PROC [subj: Node]
RETURNS [do:
BOOL ←
FALSE] = {
a: Action ← NIL;
subDo: BOOL ← FALSE;
sourceMissing, sourceNonCurrent, sourceBroken: BOOL ← FALSE;
missedList: NodeList ← NIL;
Finish:
--INTERNAL--
PROC [current: ExpensiveBool] = {
SetCurrency[subj, current];
nodesSeen.Insert[subj, subj];
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.Lookup[a] = NIL
THEN {
actionsSeen.Insert[a, a];
actions ← CONS[a, actions];
};
};
};
CheckSource:
--INTERNAL--
PROC [n: Node, which: ActionDep, optional:
BOOL] = {
CedarProcess.CheckAbort[];
InnerSetModifiability[n, goals, modifiabilitySpec];
subDo ← WorkOn[n] OR subDo;
IF (
NOT optional)
AND n.created = notExistTime
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 {
IF NOT nodesSeen.Lookup[subj] = subj THEN Finish[true];
RETURN};
a ← subj.producer.a;
IF nodesSeen.Lookup[subj] = subj
THEN {
IF subj.current = notComputed THEN ERROR;
do ← actionsSeen.Lookup[a] = a;
RETURN;
};
SELECT stackedActions.Lookup[a]
FROM
NIL => stackedActions.Insert[a, a];
a => {
Warning[IO.PutFR["Found cycle containing %g --- you lose", [rope[a.cmd]]]];
Abandon[]};
ENDCASE => ERROR;
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
THEN {
IF subj.modifiability=yes
THEN {
SetBroken[subj, TRUE];
Warning[
IO.PutFR[
"Can't %g because %g don't exist",
[rope[a.cmd]],
[rope[EnglishList[missedList].el]]
]];
};
Finish[true];
RETURN;
};
IF a.fails = true THEN {Finish[true]; RETURN};
IF
NOT subj.consistencyAsked
THEN {
[subj.consistent, subj.consistencyReason] ← a.class.CheckConsistency[a, subj];
subj.consistencyAsked ← TRUE;
};
IF subj.consistent THEN {Finish[true]; RETURN};
do ← TRUE;
Finish[false];
};