úÎ!ďŘçH‡      !"#$%&'()*+,-./012 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z {|}~€‚ƒ„…†Safe× buildJAn abstract datatype for a key/value store with build information of type i.build[Compute the hash of a given value. We typically assume cryptographic hashing, e.g. SHA256.buildA F is used for efficient tracking and sharing of build results. We use newtype Hash a = Hash a for prototyping.buildRead the build information.buildRead the value of a key.buildXRead the hash of a key's value. In some cases may be implemented more efficiently than hash . getValue k.buildWrite the build information.buildModify the build information. buildUpdate the value of a key. buildInitialise the store.    Safe+QVZbuild associates a  with every non-input key. Nothing% indicates that the key is an input.buildA $ is used to compute a value of type v<, by finding the necessary dependencies using the provided fetch :: k -> f v callback.buildsCompose two task descriptions, preferring the first one in case there are two tasks corresponding to the same key.buildLift an applicative task to  Task MonadQ. Use this function when applying monadic task combinators to applicative tasks.build*Lift a collection of applicative tasks to  Tasks MonadQ. Use this function when building applicative tasks with a monadic build system.SafeV#ŐbuildťWe assume that the fetch passed to a Task is consistent and returns values matching the keys. It is possible to switch to typed tasks to check this assumption at compile time, e.g. see Build.Task.Typed.‡buildFetch a value.ˆbuildFetch a task description."build A model for ‰<, works beautifully and allows storing the key on the disk.#build›The applicative model requires every key to be able to associate with its environment (e.g. a reader somewhere). Does not support cutoff if a key changes. !"# !"#Safe(ƒ$buildGDefines a set partition. For a function to be a valid partition, if  f k == ks, then: k in ks forall i in ks . f i == ks%buildƒGiven a task description with individual multiple-output keys, compute its "closure" supporting all possible combinations of keys.$%$%Safe)›&build-Find the dependencies of an applicative task.&&Safe*›'build)Find the dependency of a functorial task.''SafeV:F(build'Execute a monadic task on a pure store k -> v, tracking the dependencies.)build9Execute a monadic task using an effectful fetch function k -> m v, tracking the dependencies.*build6Given a description of tasks, check if a key is input.+build'Run a task with a pure lookup function.,buildRun a task in a given store.-build,Convert a task with a total lookup function k -> m v- into a task with a partial lookup function k -> m (Maybe v);. This essentially lifts the task from the type of values v to Maybe v, where the result NothingA indicates that the task failed because of a missing dependency..build,Convert a task with a total lookup function k -> m v? into a task with a lookup function that can throw exceptions k -> m (Either e v);. This essentially lifts the task from the type of values v to  Either e v, where the result Left eL indicates that the task failed because of a failed dependency lookup, and Right v yeilds the value otherwise.()*+,-.)(*+,-.SafeAÜ/build\An example of a non-deterministic task: generate a random number from a specified interval.ŠbuildXRun a non-deterministic task with a pure lookup function, listing all possible results.0buildRun a task in a given store.1buildGiven a description of tasks , an initial store, and a result1 produced by running a build system on a target key, this function returns ‹ if the key='s value is a possible result of running the associated task./01/01 Safe &'+FQTVFö2buildA typed build task.3build‰A type class for keys, equipped with an associated type family that can be used to determine the type of value corresponding to the key.5buildEThe name of the key. Useful for avoiding heterogeneous lists of keys.6build"Extract the names of dependencies.2345623456 None345KNVg‘9build^A step trace, records the resulting value, the step it last build, the step where it changed.;build1Our current model has the same representation as <M, but requires an additional invariant: if a DCT contains a trace for a key kK, then it must also contain traces for each of its non-input dependencies.<buildFAn abstract data type for a set of constructive traces equipped with F, E, G and a Œ instance.=buildBAn abstract data type for a set of verifying traces equipped with C, D and a Œ instance.>build.A trace is parameterised by the types of keys k , hashes h, as well as the result r. For verifying traces, r = h; for constructive traces,  Hash r = h.Cbuild"Record a new trace for building a key with dependencies deps6, obtaining the hashes of up-to-date values by using  fetchHash.DbuildBGiven a function to compute the hash of a key's current value, a key(, and a set of verifying traces, return ‹ if the key is up-to-date.EbuildCheck if a given key is dirty w.r.t a store.Fbuild"Record a new trace for building a key with dependencies deps6, obtaining the hashes of up-to-date values by using  fetchHash.GbuildBGiven a function to compute the hash of a key's current value, a key+, and a set of constructive traces, return  Just newValue‚ if it is possible to reconstruct it from the traces. Prefer reconstructing the currenct value, if it matches one of the traces.build6Extract the tree of input dependencies of a given key.Hbuild"Record a new trace for building a key with dependencies deps<, obtaining the hashes of up-to-date values from the given store.IbuildBGiven a function to compute the hash of a key's current value, a key1, and a set of deep constructive traces, return  Just newValue5 if it is possible to reconstruct it from the traces.Jbuild"Record a new trace for building a key with dependencies deps.KbuildBGiven a function to compute the hash of a key's current value, a key(, and a set of verifying traces, return ‹ if the key is up-to-date.9:;<=>?@BACDEFGHIJK>?@BA=CD<EFG;HI:9JK NoneNyń `build7A set of dirty keys and information about dependencies.abuildŇIf there is an entry for a key, it is an conservative approximation of its dependencies. Otherwise, we have no reasonable approximation and assume the key is always dirty (e.g. it uses an INDIRECT reference).dbuildšGiven a key-value pair and the corresponding task, a rebuilder returns a new task that has access to the build information and can use it to skip rebuilding a key if it is up to date.ebuild2Get an applicative rebuilder out of a monadic one.fbuildAlways rebuilds the key.gbuildnThis rebuilder uses modification time to decide whether a key is dirty and needs to be rebuilt. Used by Make.hbuild/If the key is dirty, rebuild it. Used by Excel.ibuildGIf the key is dirty, rebuild it and clear the dirty bit. Used by Excel.jbuild[This rebuilders uses approximate dependencies to decide whether a key needs to be rebuilt.kbuild*This rebuilder relies on verifying traces.lbuild-This rebuilder relies on constructive traces.mbuild2This rebuilder relies on deep constructive traces.nbuild-This rebuilder relies on version/step traces.`abcdefghijklmndefgcbhija`knlmNoneŠ Žbuild`Build a dependency graph given a function for computing dependencies of a key and a target key.build=Compute all keys reachable via dependecies from a target key.build2Compute the topological sort of a graph or return Nothing if the graph has cycles.‘buildpGiven a function to compute successors of a vertex, apply it recursively starting from a given vertex. Returns Nothingĺ if this process does not terminate because of cycles. Note that the current implementation is very inefficient: it trades efficiency for simplicity. The resulting list is likely to contain an exponential number of duplicates.’buildxGiven a monadic function to compute successors of a vertex, apply it recursively starting from a given vertex. Returns Nothingĺ if this process does not terminate because of cycles. Note that the current implementation is very inefficient: it trades efficiency for simplicity. The resulting list is likely to contain an exponential number of duplicates.Ž‘’ None”lobuild&A build system takes a description of j, a target key, and a store, and computes a new store, where the key and its dependencies are up to date.pbuildGiven a description of tasks , an initial store, and a result1 produced by running a build system on a target key, this function returns ‹ if the result. is a correct build outcome. Specifically: * result and storej must agree on the values of all inputs. In other words, no inputs were corrupted during the build. * result is  consistent with the tasksf, i.e. for every non-input key, the result of recomputing its task matches the value stored in the result.opop None ;<=>?KNQVÇx“buildľAn item in the queue comprises a key that needs to be built and a list of keys that are blocked on it. More efficient implementations are possible, e.g. storing blocked keys in a  Map k [k]" would allow faster queue updates.qbuildThe so-called calculation chainĄ: the order in which keys were built during the previous build, which is used as the best guess for the current build by Excel and other similar build systems.”build Lift a computation operating on i to  Store i k v.•build Lift a computation operating on  Store i k v to Store (i, j) k v.–buildpUpdate the value of a key in the store. The function takes both the current value (the first parameter of type v3) and the new value (the second parameter of type vÎ), and can potentially avoid touching the store if the value is unchanged. The current implementation simply ignores the current value, but in future this may be optimised, e.g. by comparing their hashes.rbuildŮThis scheduler constructs the dependency graph of the target key by extracting all (static) dependencies upfront, and then traversing the graph in the topological order, rebuilding keys using the supplied rebuilder.—build,Convert a task with a total lookup function k -> m v? into a task with a lookup function that can throw exceptions k -> m (Either e v);. This essentially lifts the task from the type of values v to  Either e v, where the result Left eR indicates that the task failed, e.g. because of a failed dependency lookup, and Right v yeilds the value otherwise.sbuild˙oA model of the scheduler used by Excel, which builds keys in the order used in the previous build. If a key cannot be build because its dependencies have changed and a new dependency is still dirty, the corresponding build task is abandoned and the key is moved at the end of the calculation chain, so it can be restarted when all its dependencies are up to date.˜buildyAdd a key with a list of blocked keys to the queue. If the key is already in the queue, extend its list of blocked keys.™buildDExtract a key and a list of blocked keys from the queue, or return Nothing if the queue is empty.tbuild˙|A model of the scheduler used by Bazel. We extract a key K from the queue and try to build it. There are now two cases: 1. The build fails because one of the dependencies of K is dirty. In this case we add the dirty dependency to the queue, listing K as blocked by it. 2. The build succeeds, in which case we add all keys that were previously blocked by K to the queue.ubuild˙XThis scheduler builds keys recursively: to build a key it executes the associated task, discovering its dependencies on the fly, and if one of the dependencies is dirty, the task is suspended until the dependency is rebuilt. It stores the set of keys that have already been built as part of the state to avoid executing the same task twice.šbuildRun a Task (MonadState i)E using a fetch callback operating on a larger state that contains a  Store i k v plus some extra information.vbuild˛An incorrect scheduler that builds the target key without respecting its dependencies. It produces the correct result only if all dependencies of the target key are up to date.qrstuvrsqtuvNoneVćä ›build2Excel stores a dirty bit per key and a calc chain.{build{This is not a correct build system: given a target key, it simply rebuilds it, without rebuilding any of its dependencies.|buildÝThis is a correct but non-minimal build system: given a target key it recursively rebuilds its dependencies, even if they are already up to date. There is no memoisation, therefore the a key may be built multiple times.}buildŹThis is a correct but non-minimal build system: it will rebuild keys even if they are up to date. However, it performs memoization, therefore it never builds a key twice.~buildpA model of Make: an applicative build system that uses file modification times to check if a key is up to date.buildjA model of Ninja: an applicative build system that uses verifying traces to check if a key is up to date.€buildA model of Excel: a monadic build system that stores the calculation chain from the previuos build and approximate dependencies.buildeA model of Shake: a monadic build system that uses verifying traces to check if a key is up to date.‚build˙A model of Bazel: a monadic build system that uses constructive traces to check if a key is up to date as well as for caching build results. Note that Bazel currently does not allow users to write monadic build rules: only built-in rules have access to dynamic dependencies.ƒbuild“A model of Cloud Shake: a monadic build system that uses constructive traces to check if a key is up to date as well as for caching build results.„build—A model of CloudBuild: an applicative build system that uses constructive traces to check if a key is up to date as well as for caching build results.…build–A model of Buck: an applicative build system that uses deep constructive traces to check if a key is up to date as well as for caching build results.†buildA model of Nix: a monadic build system that uses deep constructive traces to check if a key is up to date as well as for caching build results. {|}~€‚ƒ„…† {|}~„…€ƒ‚†œ !"#$%&&'()*++,--./0123456789:;<=> & - + ? @ A B C D E F G H H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w  x y z { | } ~  €  ‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—‘’˜ ™š›œž Ÿ   Ą ˘ Ł ¤ Ľ ڧ¨ build-1.0-6KaLdNNGwmTFQ8KVwgH7hE Build.Store Build.TaskBuild.SelfTracking Build.MultiBuild.Task.ApplicativeBuild.Task.FunctorBuild.Task.MonadBuild.Task.MonadPlusBuild.Task.Typed Build.TraceBuild.RebuilderBuildBuild.Scheduler Build.SystemBuild.UtilitiesStoreHashablehashHashgetInfogetValuegetHashputInfomapInfoputValue initialise$fApplicativeHash $fFunctorHash $fHashable(,)$fHashableHash $fHashable[]$fHashableInteger $fHashableInt$fEqHash $fOrdHash $fShowHashTasksTaskruncomposeliftTask liftTasksValue ValueTaskKeyKeyTask selfTrackingM selfTrackingA Partitionmulti dependencies dependency trackPuretrackisInput computePurecomputepartial exceptionalrandom computeNDcorrectBuildValueshowKeyshowDependencies$fKeyExampleKey$fShowExampleKeySTStepDCTCTVTTracekeydependsresultrecordVTverifyVT isDirtyCTrecordCT constructCT recordDCT constructDCTrecordSTverifyST $fMonoidStep$fSemigroupStep $fShowTrace $fMonoidVT $fSemigroupVT$fShowVT $fMonoidCT $fSemigroupCT$fShowCT $fMonoidDCT$fSemigroupDCT $fShowDCT $fEnumStep$fEqStep $fOrdStep $fShowStep $fShowTraceST $fMonoidST $fSemigroupST$fShowSTApproximationInfoApproximateDependenciesMakeInfoTime RebuilderadaptRebuilderperpetualRebuildermodTimeRebuilderdirtyBitRebuilderdirtyBitRebuilderWithCleanUpapproximateRebuilder vtRebuilder ctRebuilder dctRebuilder stRebuilder correctBuildChain topological restarting restarting2 suspending independent$fMonadStateiWrap $fFunctorWrap$fApplicativeWrap $fMonadWrapdumbbusymemomakeninjaexcelshakebazel cloudShake cloudBuildbucknix fetchValuefetchValueTaskbaseGHC.BaseMonad computePureNDghc-prim GHC.TypesTrueMonoiddeepDependenciesgraph reachabletopSortreachreachMQueue liftStoreliftInfo updateValuetryenqueuedequeueliftRun ExcelInfo