Cortex.Pulse.Closure


On this page
  1. Overview
  2. Context
  3. Theorem Split
  4. Failed-Ancestor Model
  5. Closure Operator
  6. Closure Facts
  7. Normalization Preservation
  8. Idempotence
Imports

Overview

Failure closure propagates failed status through the fixed topology while leaving terminal successes and skipped/rewritten nodes intact. This is the structural part of the runtime's propagateFailure: it says nothing about failure payloads, retry policy, or operator-facing diagnostics.

Context

The closure operator is the main Paper 1 recovery law: once a node fails, every still-propagatable descendant must fail too. The model keeps the operator extensional and proves the closure/fixed-point facts needed by recovery.

Theorem Split

The page defines failed ancestors, defines the closure operator, proves that one pass is failure-complete, and finishes with idempotence.

namespace Cortex.Pulsevariable {ν : Type u} {payload : Type v}

Failed-Ancestor Model

hasFailedAncestor G state node means the node has a strict failed ancestor.

def hasFailedAncestor (G : DAG ν) (state : GraphState ν payload) (node : ν) : Prop := failedNode : ν, state.status failedNode = NodeStatus.failed G.reaches failedNode node

failureClosureComplete G state means failure is closed over propagatable descendants.

A state is failure-closed when propagatable descendants of failed nodes are already marked failed.

def failureClosureComplete (G : DAG ν) (state : GraphState ν payload) : Prop := failedNode node : ν, state.status failedNode = NodeStatus.failed G.reaches failedNode node NodeStatus.propagatable (state.status node) state.status node = NodeStatus.failed

Closure Operator

propagateStatus G state node is the single-node failure-closure status update.

noncomputable def propagateStatus (G : DAG ν) (state : GraphState ν payload) (node : ν) : NodeStatus := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νNodeStatus classical All goals completed! 🐙

propagateFailure G state propagates failure to pending or waiting descendants.

noncomputable def propagateFailure (G : DAG ν) (state : GraphState ν payload) : GraphState ν payload where status := fun node => propagateStatus G state node output := state.output

Closure Facts

propagateFailure_preserves_failed shows existing failed nodes stay failed.

theorem propagateFailure_preserves_failed (G : DAG ν) (state : GraphState ν payload) {node : ν} (hFailed : state.status node = NodeStatus.failed) : (propagateFailure G state).status node = NodeStatus.failed := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhFailed:state.status node = NodeStatus.failed(propagateFailure G state).status node = NodeStatus.failed classical All goals completed! 🐙

propagateFailure_marks_failed_descendant marks propagatable failed descendants.

theorem propagateFailure_marks_failed_descendant (G : DAG ν) (state : GraphState ν payload) {node : ν} (hPropagatable : NodeStatus.propagatable (state.status node)) (hAncestor : hasFailedAncestor G state node) : (propagateFailure G state).status node = NodeStatus.failed := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhPropagatable:(state.status node).propagatablehAncestor:hasFailedAncestor G state node(propagateFailure G state).status node = NodeStatus.failed classical All goals completed! 🐙

propagatable_of_propagate recovers original propagatability after propagation.

theorem propagatable_of_propagate (G : DAG ν) (state : GraphState ν payload) {node : ν} (hPropagatable : NodeStatus.propagatable ((propagateFailure G state).status node)) : NodeStatus.propagatable (state.status node) := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhPropagatable:((propagateFailure G state).status node).propagatable(state.status node).propagatable classical ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhPropagatable:((propagateFailure G state).status node).propagatablehClosed:(state.status node).propagatable hasFailedAncestor G state node(state.status node).propagatableν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhPropagatable:((propagateFailure G state).status node).propagatablehClosed:¬((state.status node).propagatable hasFailedAncestor G state node)(state.status node).propagatable ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhPropagatable:((propagateFailure G state).status node).propagatablehClosed:(state.status node).propagatable hasFailedAncestor G state node(state.status node).propagatable All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhPropagatable:((propagateFailure G state).status node).propagatablehClosed:¬((state.status node).propagatable hasFailedAncestor G state node)(state.status node).propagatable All goals completed! 🐙

failed_after_propagate_origin identifies why a node is failed after propagation.

Every failed node after propagation either was failed already or had an original failed ancestor.

theorem failed_after_propagate (G : DAG ν) (state : GraphState ν payload) {node : ν} (hFailed : (propagateFailure G state).status node = NodeStatus.failed) : state.status node = NodeStatus.failed hasFailedAncestor G state node := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhFailed:(propagateFailure G state).status node = NodeStatus.failedstate.status node = NodeStatus.failed hasFailedAncestor G state node classical ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhFailed:(propagateFailure G state).status node = NodeStatus.failedhClosed:(state.status node).propagatable hasFailedAncestor G state nodestate.status node = NodeStatus.failed hasFailedAncestor G state nodeν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhFailed:(propagateFailure G state).status node = NodeStatus.failedhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)state.status node = NodeStatus.failed hasFailedAncestor G state node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhFailed:(propagateFailure G state).status node = NodeStatus.failedhClosed:(state.status node).propagatable hasFailedAncestor G state nodestate.status node = NodeStatus.failed hasFailedAncestor G state node All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhFailed:(propagateFailure G state).status node = NodeStatus.failedhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)state.status node = NodeStatus.failed hasFailedAncestor G state node have hOriginal : state.status node = NodeStatus.failed := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhFailed:(propagateFailure G state).status node = NodeStatus.failedstate.status node = NodeStatus.failed hasFailedAncestor G state node All goals completed! 🐙 All goals completed! 🐙

failed_after_propagate_has_original_failed_ancestor traces propagated failures.

A failed node produced by propagation still traces back to an original failed ancestor for every descendant it reaches.

theorem hasFailedAncestor_of_failed_after_reaches (G : DAG ν) (state : GraphState ν payload) {failedNode node : ν} (hFailed : (propagateFailure G state).status failedNode = NodeStatus.failed) (hReach : G.reaches failedNode node) : hasFailedAncestor G state node := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehasFailedAncestor G state node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehOriginalFailed:state.status failedNode = NodeStatus.failedhasFailedAncestor G state nodeν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehAncestor:hasFailedAncestor G state failedNodehasFailedAncestor G state node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehOriginalFailed:state.status failedNode = NodeStatus.failedhasFailedAncestor G state node All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehAncestor:hasFailedAncestor G state failedNodehasFailedAncestor G state node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode noderoot:νhRootFailed:state.status root = NodeStatus.failedhRootReach:G.reaches root failedNodehasFailedAncestor G state node All goals completed! 🐙

hasFailedAncestor_monotone lifts failed ancestors through failure-growth.

theorem hasFailedAncestor_monotone (G : DAG ν) {left right : GraphState ν payload} (hLe : GraphState.failureLe left right) {node : ν} (hAncestor : hasFailedAncestor G left node) : hasFailedAncestor G right node := ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhAncestor:hasFailedAncestor G left nodehasFailedAncestor G right node ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νfailedNode:νhFailed:left.status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehasFailedAncestor G right node All goals completed! 🐙

propagateFailure_extensive proves propagation is extensive over failed nodes.

Use this closure-law theorem when a proof only needs preservation of the already-failed set. Use propagateFailure_monotone for whole-state failure-growth reasoning through GraphState.failureLe.

theorem propagateFailure_extensive (G : DAG ν) (state : GraphState ν payload) : node : ν, state.status node = NodeStatus.failed (propagateFailure G state).status node = NodeStatus.failed := ν:Type upayload:Type vG:DAG νstate:GraphState ν payload (node : ν), state.status node = NodeStatus.failed (propagateFailure G state).status node = NodeStatus.failed intro node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadnode:νhFailed:state.status node = NodeStatus.failed(propagateFailure G state).status node = NodeStatus.failed All goals completed! 🐙

propagateStatus_monotone proves node-local failure propagation is monotone.

theorem propagateStatus_monotone (G : DAG ν) {left right : GraphState ν payload} (hLe : GraphState.failureLe left right) (node : ν) : NodeStatus.failureLe (propagateStatus G left node) (propagateStatus G right node) := ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:ν(propagateStatus G left node).failureLe (propagateStatus G right node) classical ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left node(propagateStatus G left node).failureLe (propagateStatus G right node)ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:¬((left.status node).propagatable hasFailedAncestor G left node)(propagateStatus G left node).failureLe (propagateStatus G right node) ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left node(propagateStatus G left node).failureLe (propagateStatus G right node) have hRightFailed : propagateStatus G right node = NodeStatus.failed := ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:ν(propagateStatus G left node).failureLe (propagateStatus G right node) ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehSame:left.status node = right.status nodepropagateStatus G right node = NodeStatus.failedν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehFailure:(left.status node).propagatable right.status node = NodeStatus.failedpropagateStatus G right node = NodeStatus.failed ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehSame:left.status node = right.status nodepropagateStatus G right node = NodeStatus.failed have hRightClosed : NodeStatus.propagatable (right.status node) hasFailedAncestor G right node := ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:ν(propagateStatus G left node).failureLe (propagateStatus G right node) ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehSame:left.status node = right.status node(right.status node).propagatableν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehSame:left.status node = right.status nodehasFailedAncestor G right node ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehSame:left.status node = right.status node(right.status node).propagatable All goals completed! 🐙 ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehSame:left.status node = right.status nodehasFailedAncestor G right node All goals completed! 🐙 All goals completed! 🐙 ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehFailure:(left.status node).propagatable right.status node = NodeStatus.failedpropagateStatus G right node = NodeStatus.failed ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left node_hLeftPropagatable:(left.status node).propagatablehRightStatus:right.status node = NodeStatus.failedpropagateStatus G right node = NodeStatus.failed All goals completed! 🐙 have hLeftFailed : propagateStatus G left node = NodeStatus.failed := ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:ν(propagateStatus G left node).failureLe (propagateStatus G right node) All goals completed! 🐙 ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:(left.status node).propagatable hasFailedAncestor G left nodehRightFailed:propagateStatus G right node = NodeStatus.failedhLeftFailed:propagateStatus G left node = NodeStatus.failedNodeStatus.failed.failureLe NodeStatus.failed All goals completed! 🐙 ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:¬((left.status node).propagatable hasFailedAncestor G left node)(propagateStatus G left node).failureLe (propagateStatus G right node) ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:¬((left.status node).propagatable hasFailedAncestor G left node)hRightClosed:(right.status node).propagatable hasFailedAncestor G right node(propagateStatus G left node).failureLe (propagateStatus G right node)ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:¬((left.status node).propagatable hasFailedAncestor G left node)hRightClosed:¬((right.status node).propagatable hasFailedAncestor G right node)(propagateStatus G left node).failureLe (propagateStatus G right node) ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:¬((left.status node).propagatable hasFailedAncestor G left node)hRightClosed:(right.status node).propagatable hasFailedAncestor G right node(propagateStatus G left node).failureLe (propagateStatus G right node) ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:¬((left.status node).propagatable hasFailedAncestor G left node)hRightClosed:(right.status node).propagatable hasFailedAncestor G right nodehLeftPropagatable:(left.status node).propagatable(propagateStatus G left node).failureLe (propagateStatus G right node) All goals completed! 🐙 ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:νhLeftClosed:¬((left.status node).propagatable hasFailedAncestor G left node)hRightClosed:¬((right.status node).propagatable hasFailedAncestor G right node)(propagateStatus G left node).failureLe (propagateStatus G right node) All goals completed! 🐙

propagateFailure_monotone proves failure closure is monotone over failure-growth.

theorem propagateFailure_monotone (G : DAG ν) {left right : GraphState ν payload} (hLe : GraphState.failureLe left right) : GraphState.failureLe (propagateFailure G left) (propagateFailure G right) := ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe right(propagateFailure G left).failureLe (propagateFailure G right) ν:Type upayload:Type vG:DAG νleft:GraphState ν payloadright:GraphState ν payloadhLe:left.failureLe rightnode:ν((propagateFailure G left).status node).failureLe ((propagateFailure G right).status node) All goals completed! 🐙

propagateFailure_failureClosureComplete proves propagation reaches closure.

theorem propagateFailure_failureClosureComplete (G : DAG ν) (state : GraphState ν payload) : failureClosureComplete G (propagateFailure G state) := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailureClosureComplete G (propagateFailure G state) intro failedNode ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:ν(propagateFailure G state).status failedNode = NodeStatus.failed G.reaches failedNode node ((propagateFailure G state).status node).propagatable (propagateFailure G state).status node = NodeStatus.failed ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedG.reaches failedNode node ((propagateFailure G state).status node).propagatable (propagateFailure G state).status node = NodeStatus.failed ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode node((propagateFailure G state).status node).propagatable (propagateFailure G state).status node = NodeStatus.failed ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehPropagatable:((propagateFailure G state).status node).propagatable(propagateFailure G state).status node = NodeStatus.failed ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehPropagatable:((propagateFailure G state).status node).propagatablehAncestor:hasFailedAncestor G state node(propagateFailure G state).status node = NodeStatus.failed ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadfailedNode:νnode:νhFailed:(propagateFailure G state).status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehPropagatable:((propagateFailure G state).status node).propagatablehAncestor:hasFailedAncestor G state nodehOriginalPropagatable:(state.status node).propagatable(propagateFailure G state).status node = NodeStatus.failed All goals completed! 🐙

Normalization Preservation

propagateFailure_preserves_noRunning preserves the absence of running nodes.

theorem propagateFailure_preserves_noRunning (G : DAG ν) (state : GraphState ν payload) (hNoRunning : GraphState.noRunningNodes state) : GraphState.noRunningNodes (propagateFailure G state) := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoRunning:state.noRunningNodes(propagateFailure G state).noRunningNodes classical ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:ν(propagateFailure G state).status node NodeStatus.running ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhClosed:(state.status node).propagatable hasFailedAncestor G state node(propagateFailure G state).status node NodeStatus.runningν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)(propagateFailure G state).status node NodeStatus.running ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhClosed:(state.status node).propagatable hasFailedAncestor G state node(propagateFailure G state).status node NodeStatus.running ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhClosed:(state.status node).propagatable hasFailedAncestor G state nodehRunning:(propagateFailure G state).status node = NodeStatus.runningFalse All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)(propagateFailure G state).status node NodeStatus.running All goals completed! 🐙

propagateFailure_preserves_noInterrupted preserves the absence of interrupted nodes.

theorem propagateFailure_preserves_noInterrupted (G : DAG ν) (state : GraphState ν payload) (hNoInterrupted : GraphState.noInterruptedNodes state) : GraphState.noInterruptedNodes (propagateFailure G state) := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoInterrupted:state.noInterruptedNodes(propagateFailure G state).noInterruptedNodes classical ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoInterrupted:state.noInterruptedNodesnode:ν(propagateFailure G state).status node NodeStatus.interrupted ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoInterrupted:state.noInterruptedNodesnode:νhClosed:(state.status node).propagatable hasFailedAncestor G state node(propagateFailure G state).status node NodeStatus.interruptedν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoInterrupted:state.noInterruptedNodesnode:νhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)(propagateFailure G state).status node NodeStatus.interrupted ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoInterrupted:state.noInterruptedNodesnode:νhClosed:(state.status node).propagatable hasFailedAncestor G state node(propagateFailure G state).status node NodeStatus.interrupted ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoInterrupted:state.noInterruptedNodesnode:νhClosed:(state.status node).propagatable hasFailedAncestor G state nodehInterrupted:(propagateFailure G state).status node = NodeStatus.interruptedFalse All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhNoInterrupted:state.noInterruptedNodesnode:νhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)(propagateFailure G state).status node NodeStatus.interrupted All goals completed! 🐙

propagateFailure_preserves_topologyDomain preserves off-topology absence.

theorem propagateFailure_preserves_topologyDomain (G : DAG ν) (state : GraphState ν payload) (hDomain : GraphState.topologyDomain G state) : GraphState.topologyDomain G (propagateFailure G state) := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G stateGraphState.topologyDomain G (propagateFailure G state) classical intro node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statenode:νhNotMem:node G.nodes(propagateFailure G state).status node = NodeStatus.pending (propagateFailure G state).output node = none ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statenode:νhNotMem:node G.nodeshStatus:state.status node = NodeStatus.pendinghOutput:state.output node = none(propagateFailure G state).status node = NodeStatus.pending (propagateFailure G state).output node = none have hNoAncestor : ¬ hasFailedAncestor G state node := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G stateGraphState.topologyDomain G (propagateFailure G state) ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statenode:νhNotMem:node G.nodeshStatus:state.status node = NodeStatus.pendinghOutput:state.output node = nonehAncestor:hasFailedAncestor G state nodeFalse ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statenode:νhNotMem:node G.nodeshStatus:state.status node = NodeStatus.pendinghOutput:state.output node = none_failedNode:ν_hFailed:state.status _failedNode = NodeStatus.failedhReach:G.reaches _failedNode nodeFalse All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statenode:νhNotMem:node G.nodeshStatus:state.status node = NodeStatus.pendinghOutput:state.output node = nonehNoAncestor:¬hasFailedAncestor G state node(propagateFailure G state).status node = NodeStatus.pendingν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statenode:νhNotMem:node G.nodeshStatus:state.status node = NodeStatus.pendinghOutput:state.output node = nonehNoAncestor:¬hasFailedAncestor G state node(propagateFailure G state).output node = none ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statenode:νhNotMem:node G.nodeshStatus:state.status node = NodeStatus.pendinghOutput:state.output node = nonehNoAncestor:¬hasFailedAncestor G state node(propagateFailure G state).status node = NodeStatus.pending All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statenode:νhNotMem:node G.nodeshStatus:state.status node = NodeStatus.pendinghOutput:state.output node = nonehNoAncestor:¬hasFailedAncestor G state node(propagateFailure G state).output node = none All goals completed! 🐙

propagateFailure_preserves_outputsRespectStatuses preserves output ownership.

theorem propagateFailure_preserves_outputsRespectStatuses (G : DAG ν) (state : GraphState ν payload) (hOutputs : GraphState.outputsRespectStatuses state) : GraphState.outputsRespectStatuses (propagateFailure G state) := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatuses(propagateFailure G state).outputsRespectStatuses classical intro node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payload(propagateFailure G state).output node = some value ((propagateFailure G state).status node).mayHaveOutput ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some value((propagateFailure G state).status node).mayHaveOutput ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state node((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:¬((state.status node).propagatable hasFailedAncestor G state node)((propagateFailure G state).status node).mayHaveOutput ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state node((propagateFailure G state).status node).mayHaveOutput ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutput((propagateFailure G state).status node).mayHaveOutput ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.pending((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.running((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.completed((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.failed((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.skipped((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.interrupted((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.waiting((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.rewritten((propagateFailure G state).status node).mayHaveOutput ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.pending((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.running((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.completed((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.failed((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.skipped((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.interrupted((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.waiting((propagateFailure G state).status node).mayHaveOutputν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:(state.status node).propagatable hasFailedAncestor G state nodehMayHaveOutput:(state.status node).mayHaveOutputhStatus:state.status node = NodeStatus.rewritten((propagateFailure G state).status node).mayHaveOutput All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(propagateFailure G state).output node = some valuehClosed:¬((state.status node).propagatable hasFailedAncestor G state node)((propagateFailure G state).status node).mayHaveOutput All goals completed! 🐙

propagateFailure_preserves_outputsCompleteForStatuses preserves required outputs.

theorem propagateFailure_preserves_outputsCompleteForStatuses (G : DAG ν) (state : GraphState ν payload) (hOutputs : GraphState.outputsCompleteForStatuses state) : GraphState.outputsCompleteForStatuses (propagateFailure G state) := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuses(propagateFailure G state).outputsCompleteForStatuses classical intro node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((propagateFailure G state).status node).requiresOutput value, (propagateFailure G state).output node = some value ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((propagateFailure G state).status node).requiresOutputhClosed:(state.status node).propagatable hasFailedAncestor G state node value, (propagateFailure G state).output node = some valueν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((propagateFailure G state).status node).requiresOutputhClosed:¬((state.status node).propagatable hasFailedAncestor G state node) value, (propagateFailure G state).output node = some value ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((propagateFailure G state).status node).requiresOutputhClosed:(state.status node).propagatable hasFailedAncestor G state node value, (propagateFailure G state).output node = some value All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((propagateFailure G state).status node).requiresOutputhClosed:¬((state.status node).propagatable hasFailedAncestor G state node) value, (propagateFailure G state).output node = some value have hOriginalRequires : NodeStatus.requiresOutput (state.status node) := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuses(propagateFailure G state).outputsCompleteForStatuses All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((propagateFailure G state).status node).requiresOutputhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)hOriginalRequires:(state.status node).requiresOutputvalue:payloadhOutput:state.output node = some value value, (propagateFailure G state).output node = some value exact value, ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((propagateFailure G state).status node).requiresOutputhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)hOriginalRequires:(state.status node).requiresOutputvalue:payloadhOutput:state.output node = some value(propagateFailure G state).output node = some value All goals completed! 🐙

Idempotence

propagateFailure_of_failureClosureComplete makes failure-closed states fixed points.

theorem propagateFailure_of_failureClosureComplete (G : DAG ν) (state : GraphState ν payload) (hComplete : failureClosureComplete G state) : propagateFailure G state = state := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statepropagateFailure G state = state classical ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:ν(propagateFailure G state).status node = state.status nodeν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:νa✝:payload(propagateFailure G state).output node = some a✝ state.output node = some a✝ ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:ν(propagateFailure G state).status node = state.status node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:νhClosed:(state.status node).propagatable hasFailedAncestor G state node(propagateFailure G state).status node = state.status nodeν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:νhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)(propagateFailure G state).status node = state.status node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:νhClosed:(state.status node).propagatable hasFailedAncestor G state node(propagateFailure G state).status node = state.status node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:νhClosed:(state.status node).propagatable hasFailedAncestor G state nodefailedNode:νhFailed:state.status failedNode = NodeStatus.failedhReach:G.reaches failedNode node(propagateFailure G state).status node = state.status node ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:νhClosed:(state.status node).propagatable hasFailedAncestor G state nodefailedNode:νhFailed:state.status failedNode = NodeStatus.failedhReach:G.reaches failedNode nodehNodeFailed:state.status node = NodeStatus.failed(propagateFailure G state).status node = state.status node All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:νhClosed:¬((state.status node).propagatable hasFailedAncestor G state node)(propagateFailure G state).status node = state.status node All goals completed! 🐙 ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadhComplete:failureClosureComplete G statenode:νa✝:payload(propagateFailure G state).output node = some a✝ state.output node = some a✝ All goals completed! 🐙

propagateFailure_idempotent proves failure propagation is idempotent.

theorem propagateFailure_idempotent (G : DAG ν) (state : GraphState ν payload) : propagateFailure G (propagateFailure G state) = propagateFailure G state := ν:Type upayload:Type vG:DAG νstate:GraphState ν payloadpropagateFailure G (propagateFailure G state) = propagateFailure G state All goals completed! 🐙end Cortex.Pulse