On 6/30/17 Jun 30 -10:35 AM, Faré wrote: >> On 6/30/17 Jun 30 -10:11 AM, Faré wrote: >>> First, can you confirm that the compute-action-stamp called by >>> mark-operation-done called by the perform :after method on define-op >>> returns the correct value? >> >> Hm. I don't see any such after method. All I see is this: >> >> (defmethod perform ((o define-op) (s system)) > ... >> (if-let ((pathname (first (input-files o s))))) > ... > This call to input-files is problematic, as it will cause the wrong > value to be cached, before you recorded your input-files. Note that > you might have to invalidate the cached input-files anyway, because it > may already have been called by compute-action-stamp at that point. > > But I meant the general perform :after method and mark-operation-done > method from action.lisp.
OK, I see this: (defmethod perform :after ((o operation) (c component)) (mark-operation-done o c)) That's going to compute a time stamp for the operation. I think that's OK, because that will be done after the first time the DEFINE-OP is executed. Ideally, when we go to do it the second time, this timestamp will be compared with the last write time on the input files (in this case a revision-number.lisp-expr file), and should trigger the DEFINE-OP to be done again. But obviously I'm missing something, since this is not happening. Actually, there are a bunch of things I don't understand, including: 1. When I invoke LOAD-OP the second time, why is ACTION-UP-TO-DATE-P never called? What short-circuits this? 2. COMPONENT-OPERATION-TIME is called on DEFINE-OP of SYSTEM at what looks like the right time (as well as being called a bunch of other times, presumably to check that it's up-to-date with respect to downstream components). 3. Looks like COMPUTE-ACTION-STATUS calls COMPUTE-ACTION-STAMP. Looks like that is where we compute whether or not the operation is up-to-date wrt the input files. 4. This is likely to be the problem: we compare the time stamp of the input files against the earliest time stamp of the output files. But there are no output files from the define-op, so we do UP-TO-DATE-P = (STAMP<= <number> NIL) and STAMP<= is defined to always be true if the second argument is null. So there is no point in the algorithm -- or at least no point that I can see -- where we compare the input-file time stamps against the component-operation-time.... I could butcher that in, but I'm a little worried -- the logic in COMPUTE-ACTION-STAMP is quite subtle. Anyway, that's how I'm proceeding. > >> At any >> rate, I'm having a hard time tracking down exactly where we determine >> whether or not a define-op needs redoing. > Ultimately, it boils down to (compute-action-stamp plan operation > component [nil]) as called by compute-action-status in plan.lisp. And > *that* will call input-files. > >> The caching code makes things >> much more efficient, but it also effectively camouflages the algorithm.... >> > Not just "more efficient", but in some cases keeps O(n) what might be > a much higher polynomial (or exponential?) when a module's input-files > recursively depend on its contents (e.g. for warning checking). But > yes, sometimes you need to invalidate the cache, and this looks like > one of those times to me. > > —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org > Too many people are thinking of security instead of opportunity. They seem > more afraid of life than death. > — James F. Byrnes >