Blocks world 2026-10-24
The blocks world is a classical planning model of movable blocks arranged in stacks on an unlimited table. Each block has one support, each block supports at most one other block, and the support relation has no directed cycle. A clear block can move onto another clear block or onto the table. In a direct-transfer STRIPS representation, an action includes the entire pickup-and-placement operation; a separate holding or empty-hand planning fluent is unnecessary unless the action model explicitly splits those operations.
The table has unlimited capacity, so its availability must not be deleted when a block is placed there. Planning state invariants connect the predicate describing a clear block to the absence of any block directly above it. Goal interaction in planning makes this small model useful for testing automated planning methods.
Suppose a predicate accepts some and rejects some . Dropping its initial accepted list prefix maps both the empty list and the singleton to the empty list, but maps the extensions by to different lists. A direct list fold cannot do this: its combining function receives the same head and the same folded-tail summary in both cases. This is an instance of the fold factorisation criterion. An auxiliary list fold retaining more information followed by projection is not ruled out.
Write for the table. The positive initial planning fluents read from the original figure areThe static type facts are , and ; the table is not a block. With an explicit table-availability predicate, take to be permanently true. Under the closed-world assumption, all other well-typed initial planning fluents are false; in particular, is not clear.
The goal is the partial-state conjunctionIt need not redundantly prescribe every final fact. With only these three blocks and a valid blocks world state, the completed stack also places on the table and leaves clear.
Ground as distinct blocks. For , takeThus a clear block leaves its block support, makes that support clear, and joins the unlimited table. persists, and table availability is never deleted. Requiring to be a block excludes a redundant table-to-table action. The static predicates need not be stored as time-varying planning fluents.
Use for the agent, monster, gold and arrow, and abbreviate to . A physically safe STRIPS plan isEvery movement follows a listed adjacency predicate. The shot is taken from while the arrow is held, and kills the monster before entry into . The pit at is never entered. The pickup establishes possession of the gold, and the last four movements restore the exit location while preserving that possession. Thus ten actions achieve the formal goal and the intended safe return; arriving at the exit is the source model’s representation of leaving.
Yes. Define the combining function as follows:For the fusion derivation use the identity reconstruction
takeP :: (a -> Bool) -> [a] -> [a]
takeP p = foldr step []
where
step x rest = if p x then x : rest else []foldr (:) [], take , and choose the displayed step as . The function is strict in the input list, , and its cons equation is exactly . Fusion gives the implementation. On a false test, step does not demand the folded tail, so the implementation can terminate after a finite list prefix even when the remaining list is infinite or undefined. An undefined predicate result at a tested element makes both definitions undefined.In general, no direct list fold with result type
[a] can implement dropWhile p. Choose total values for which and . The results on [] and [u] are both []. A hypothetical implementation foldr h z would therefore receive identical folded-tail values when extending either input by the same head . Yet the required outputs are [v] and [v,u], respectively. This contradicts the fold factorisation criterion: the combining function cannot distinguish information already discarded by its tail summary.The claim concerns a direct same-result-type list fold. A list fold returning extra information, followed by a projection, is possible: a pair can retain both the original tail and the dropped list suffix. Also, special predicates can have direct list folds: a constantly false predicate gives the identity; a constantly true predicate can use
foldr (\_ r -> r) [], which correctly diverges when it must traverse an infinite spine. Those special cases do not supply an implementation for an arbitrary predicate.The necessary definedness condition is local: every predicate application actually reached before the first false result must produce a Boolean value. No condition is needed on predicate applications after that first false result, because the list suffix is then returned without further testing. If a reached test is bottom at a known cons cell, the reconstructed list is bottom at that position, while the original list still exposes a cons there; equality fails.
To prove sufficiency on finite lists, induct on the spine. The empty case gives
[] ++ [] = []. At a true test the left list prefix contributes the head, and the induction hypothesis reconstructs the tail. At a false test the list prefix is empty and the list suffix is the whole current list. For an infinite true-tested list prefix, every finite output list prefix is copied correctly; the infinite list prefix hides the possibly divergent list suffix computation. A partial spine ending in bottom is reconstructed up to exactly the same bottom. Thus finiteness is sufficient for an elementary induction proof but is not itself necessary for the identity.For the uniform list fold calculation in part (f), use the convenient stronger assumption that the input is a finite total list and the predicate terminates on every element of that list. This makes the reconstruction identity available on every list suffix, not only on the list suffixes visited by the original list prefix scan. A total predicate on the element type ensures this uniformly over all finite total inputs.
Yes, under the finite total assumption in part (d). The pair result retains enough information to reconstruct the tail; the Take , and . The base image is . If is true, the recursive equation gives the first branch. If it is false, part (d), applied to the tail, gives , so the second branch becomes . These are precisely the fusion compatibility equations. Finite structural induction establishes the desired equality; it does not require extending the restricted-domain hypothesis to undefined predicate applications.
~ pattern keeps its two components lazy:spanFold :: (a -> Bool) -> [a] -> ([a], [a])
spanFold p = foldr step ([], [])
where
step x ~(ys,zs)
| p x = (x:ys,zs)
| otherwise = ([],x:(ys ++ zs))The qualification matters. If is false but is undefined, ordinary
spanP p [v,u] can return the untouched list suffix immediately, whereas the reconstruction through spanFold p [u] cannot recover that list suffix. The weaker condition needed only for the single reconstruction identity in (d) is therefore insufficient for this particular list fold on all list suffixes. The stronger totality condition stated there supplies exactly the missing premise.The following predicate also checks the square's shape; The row tests guarantee that each row has length and contains each allowed symbol once. Because
sort is the three-way sorting function from Question 2:valid :: [[Int]] -> Bool
valid rows =
let n = length rows
symbols = [1..n]
goodRows = all (\r -> sort r == symbols) rows
goodColumns = all (\j -> sort [r !! j | r <- rows] == symbols)
[0..n-1]
in goodRows && goodColumns
latin :: Int -> [[[Int]]]
latin = filter valid . squares&& tests this condition first, the later column indexing is safe for a finite total input. The column tests establish the remaining Latin-square condition. Filtering therefore retains precisely the valid squares; it does not remove any different ordering of rows, columns or symbols as an alleged symmetry duplicate.Share the recursive pair and inspect the predicate once:For a finite list, structural induction establishes that
partition :: (a -> Bool) -> [a] -> ([a],[a])
partition _ [] = ([],[])
partition p (x:xs)
| p x = (x:yes,no)
| otherwise = (yes,x:no)
where ~(yes,no) = partition p xsyes and no are the two required filtered subsequences. The guard evaluates p x once and prepends x to exactly one output, preserving input order in both. Fully consuming both results uses predicate applications and additional work. Sharing the recursive result avoids making separate recursive traversals. This is a stable list partition.Fold into a membership predicate:At an empty tree the predicate is always false. At a nonempty binary search tree, an unequal query can occur only in the indicated child, while equality finds the root. This proves correctness inductively. Under lazy evaluation, the unused folded child is not demanded; lookup follows one root-to-leaf route and takes comparisons in a tree of height . Defining the predicate by a fold does not require visiting both subtrees for each query.
find :: Ord a => Tree a -> a -> Bool
find = foldTree node (const False)
where
node left x right q = case compare q x of
LT -> left q
EQ -> True
GT -> right q Predicate prefix-suffix reconstruction 2026-10-24
Concatenating the initial list prefix accepted by a predicate with the remaining list suffix reconstructs the input, provided every test reached before the first false result terminates. Prove the finite case by structural induction: a true test copies the head, and a false test returns the untouched list suffix. An undefined reached test is an obstruction because reconstruction loses an exposed cons cell. An infinite all-true list prefix can still reconstruct the input, since list concatenation never demands its second argument there.
Predicate span 2026-10-24
Splitting a list into its longest initially accepted list prefix and the remaining list suffix. On finite total lists with terminating predicate tests, the pair is a direct right fold: the true branch prepends to the first component; the false branch reconstructs the original tail by concatenating the two tail components and puts the current head before it. The richer pair result retains information that a direct dropped-list suffix list fold loses. Conventional recursive span is strict in the input spine; a literal pair of its two projections can expose an outer pair even on bottom, so partial-value equations require care.
Stable list partition 2026-10-24
Split a list into the subsequence satisfying a predicate and the subsequence failing it, preserving relative order in both. One recursive traversal computes the pair for the tail once, evaluates the head's predicate once and prepends the head to the appropriate component. A shared irrefutable pair binding preserves lazy access to either component. Fully consuming both finite outputs takes linear time in addition to predicate evaluation costs.
Tree fold 2026-10-24
A structural recursion replacing the empty binary tree by a value and a nonempty node by a combining function on its two folded children and root label. The result type may itself be a function type, allowing a fold to construct a membership predicate or a difference list rather than traversing all branches for every subsequent query.