Cortex.Pulse.Fact
On this page
Imports
import Cortex.Pulse.Frontier
import Mathlib.Data.List.Pairwise
import Mathlib.Data.List.Perm.BasicOverview
Frontier workers produce node-local facts. The fixed-topology kernel only needs the node key, the resulting status, and an optional output; payload and failure detail contents remain abstract.
Context
The runtime applies a wave of frontier results by folding node-local updates into a graph state. The theorem-level fact this page needs is that two results for distinct nodes commute because they update disjoint keys.
Theorem Split
The page defines abstract worker outcomes, packages them as durable node
results, and proves the disjoint-key commutativity lemma used by later
frontier-fold proofs. Arbitrary node facts are not assumed safe: the
Admissible predicate records the frontier precondition needed by
preservation theorems.
namespace Cortex.PulseWorker Outcomes
NodeOutcome payload is the abstract worker outcome for a single node.
inductive NodeOutcome (payload : Type v) : Type v where
| succeeded : payload → NodeOutcome payload
| skipped : NodeOutcome payload
| suspended : NodeOutcome payload
| failed : NodeOutcome payload
| timedOut : NodeOutcome payload
| cancelled : NodeOutcome payload
| shutdown : NodeOutcome payload
| runCancelled : NodeOutcome payload
| rewritten : payload → NodeOutcome payload
deriving Reprnamespace NodeOutcomevariable {payload : Type v}
NodeOutcome.status outcome is the status contributed by an outcome.
def status : NodeOutcome payload → NodeStatus
| succeeded _ => NodeStatus.completed
| skipped => NodeStatus.skipped
| suspended => NodeStatus.waiting
| failed => NodeStatus.failed
| timedOut => NodeStatus.failed
| cancelled => NodeStatus.interrupted
| shutdown => NodeStatus.interrupted
| runCancelled => NodeStatus.interrupted
| rewritten _ => NodeStatus.rewritten
NodeOutcome.output outcome is the optional output contributed by an outcome.
def output : NodeOutcome payload → Option payload
| succeeded value => some value
| rewritten value => some value
| skipped => none
| suspended => none
| failed => none
| timedOut => none
| cancelled => none
| shutdown => none
| runCancelled => none
output_respects_status says emitted outputs match statuses that own payloads.
theorem output_respects_status
(outcome : NodeOutcome payload)
(value : payload)
(hOutput : output outcome = some value) :
NodeStatus.mayHaveOutput (status outcome) := payload:Type voutcome:NodeOutcome payloadvalue:payloadhOutput:outcome.output = some value⊢ outcome.status.mayHaveOutput
payload:Type vvalue:payloada✝:payloadhOutput:(succeeded a✝).output = some value⊢ (succeeded a✝).status.mayHaveOutputpayload:Type vvalue:payloadhOutput:skipped.output = some value⊢ skipped.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:suspended.output = some value⊢ suspended.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:failed.output = some value⊢ failed.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:timedOut.output = some value⊢ timedOut.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:cancelled.output = some value⊢ cancelled.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:shutdown.output = some value⊢ shutdown.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:runCancelled.output = some value⊢ runCancelled.status.mayHaveOutputpayload:Type vvalue:payloada✝:payloadhOutput:(rewritten a✝).output = some value⊢ (rewritten a✝).status.mayHaveOutput payload:Type vvalue:payloada✝:payloadhOutput:(succeeded a✝).output = some value⊢ (succeeded a✝).status.mayHaveOutputpayload:Type vvalue:payloadhOutput:skipped.output = some value⊢ skipped.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:suspended.output = some value⊢ suspended.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:failed.output = some value⊢ failed.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:timedOut.output = some value⊢ timedOut.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:cancelled.output = some value⊢ cancelled.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:shutdown.output = some value⊢ shutdown.status.mayHaveOutputpayload:Type vvalue:payloadhOutput:runCancelled.output = some value⊢ runCancelled.status.mayHaveOutputpayload:Type vvalue:payloada✝:payloadhOutput:(rewritten a✝).output = some value⊢ (rewritten a✝).status.mayHaveOutput All goals completed! 🐙
status_ne_running says durable worker outcomes never write running.
theorem status_ne_running
(outcome : NodeOutcome payload) :
status outcome ≠ NodeStatus.running := payload:Type voutcome:NodeOutcome payload⊢ outcome.status ≠ NodeStatus.running
payload:Type va✝:payload⊢ (succeeded a✝).status ≠ NodeStatus.runningpayload:Type v⊢ skipped.status ≠ NodeStatus.runningpayload:Type v⊢ suspended.status ≠ NodeStatus.runningpayload:Type v⊢ failed.status ≠ NodeStatus.runningpayload:Type v⊢ timedOut.status ≠ NodeStatus.runningpayload:Type v⊢ cancelled.status ≠ NodeStatus.runningpayload:Type v⊢ shutdown.status ≠ NodeStatus.runningpayload:Type v⊢ runCancelled.status ≠ NodeStatus.runningpayload:Type va✝:payload⊢ (rewritten a✝).status ≠ NodeStatus.running payload:Type va✝:payload⊢ (succeeded a✝).status ≠ NodeStatus.runningpayload:Type v⊢ skipped.status ≠ NodeStatus.runningpayload:Type v⊢ suspended.status ≠ NodeStatus.runningpayload:Type v⊢ failed.status ≠ NodeStatus.runningpayload:Type v⊢ timedOut.status ≠ NodeStatus.runningpayload:Type v⊢ cancelled.status ≠ NodeStatus.runningpayload:Type v⊢ shutdown.status ≠ NodeStatus.runningpayload:Type v⊢ runCancelled.status ≠ NodeStatus.runningpayload:Type va✝:payload⊢ (rewritten a✝).status ≠ NodeStatus.running All goals completed! 🐙end NodeOutcomeDurable Node Facts
NodeResult ν payload is the durable fact emitted for one node.
structure NodeResult (ν : Type u) (payload : Type v) where
node is the state key updated by this fact.
node : ν
outcome is the abstract result for the node.
outcome : NodeOutcome payloadnamespace NodeResultvariable {ν : Type u} {payload : Type v}
InTopology G result says a durable node fact targets a topology node.
def InTopology (G : DAG ν) (result : NodeResult ν payload) : Prop :=
result.node ∈ G.nodes
Admissible G state result says a node fact came from the executable frontier.
def Admissible
(G : DAG ν)
(state : GraphState ν payload)
(result : NodeResult ν payload) : Prop :=
InTopology G result ∧ DirectReady G state result.node
admissible_inTopology extracts the topology target precondition.
theorem admissible_inTopology
{G : DAG ν}
{state : GraphState ν payload}
{result : NodeResult ν payload}
(hResult : Admissible G state result) :
InTopology G result :=
hResult.1
admissible_directReady extracts the executable-frontier precondition.
theorem admissible_directReady
{G : DAG ν}
{state : GraphState ν payload}
{result : NodeResult ν payload}
(hResult : Admissible G state result) :
DirectReady G state result.node :=
hResult.2
admissible_ready turns an admissible runtime fact into proof-level readiness.
theorem admissible_ready
(G : DAG ν)
(state : GraphState ν payload)
(result : NodeResult ν payload)
(hCausal : CausalHistoryClosed G state)
(hResult : Admissible G state result) :
Ready G state result.node :=
directReady_ready_of_causalHistoryClosed G state hCausal hResult.2
applyNodeFact result state applies a node-local fact to the graph state.
def applyNodeFact [DecidableEq ν]
(result : NodeResult ν payload)
(state : GraphState ν payload) : GraphState ν payload where
status := fun n =>
if n = result.node then result.outcome.status else state.status n
output := fun n =>
if n = result.node then result.outcome.output else state.output nInvariant Preservation
applyNodeFact_preserves_topologyDomain preserves off-topology absence.
theorem applyNodeFact_preserves_topologyDomain [DecidableEq ν]
(G : DAG ν)
(result : NodeResult ν payload)
(state : GraphState ν payload)
(hDomain : GraphState.topologyDomain G state)
(hResult : InTopology G result) :
GraphState.topologyDomain G (applyNodeFact result state) := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G result⊢ GraphState.topologyDomain G (result.applyNodeFact state)
intro node ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodes⊢ (result.applyNodeFact state).status node = NodeStatus.pending ∧ (result.applyNodeFact state).output node = none
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:node = result.node⊢ (result.applyNodeFact state).status node = NodeStatus.pending ∧ (result.applyNodeFact state).output node = noneν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:¬node = result.node⊢ (result.applyNodeFact state).status node = NodeStatus.pending ∧ (result.applyNodeFact state).output node = none
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:node = result.node⊢ (result.applyNodeFact state).status node = NodeStatus.pending ∧ (result.applyNodeFact state).output node = none ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resulthNotMem:result.node ∉ G.nodes⊢ (result.applyNodeFact state).status result.node = NodeStatus.pending ∧
(result.applyNodeFact state).output result.node = none
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:¬node = result.node⊢ (result.applyNodeFact state).status node = NodeStatus.pending ∧ (result.applyNodeFact state).output node = none ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:¬node = result.nodehStatus:state.status node = NodeStatus.pendinghOutput:state.output node = none⊢ (result.applyNodeFact state).status node = NodeStatus.pending ∧ (result.applyNodeFact state).output node = none
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:¬node = result.nodehStatus:state.status node = NodeStatus.pendinghOutput:state.output node = none⊢ (result.applyNodeFact state).status node = NodeStatus.pendingν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:¬node = result.nodehStatus:state.status node = NodeStatus.pendinghOutput:state.output node = none⊢ (result.applyNodeFact state).output node = none
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:¬node = result.nodehStatus:state.status node = NodeStatus.pendinghOutput:state.output node = none⊢ (result.applyNodeFact state).status node = NodeStatus.pending All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:InTopology G resultnode:νhNotMem:node ∉ G.nodeshNode:¬node = result.nodehStatus:state.status node = NodeStatus.pendinghOutput:state.output node = none⊢ (result.applyNodeFact state).output node = none All goals completed! 🐙
applyNodeFact_preserves_outputsRespectStatuses preserves output ownership.
theorem applyNodeFact_preserves_outputsRespectStatuses [DecidableEq ν]
(result : NodeResult ν payload)
(state : GraphState ν payload)
(hOutputs : GraphState.outputsRespectStatuses state) :
GraphState.outputsRespectStatuses (applyNodeFact result state) := ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatuses⊢ (result.applyNodeFact state).outputsRespectStatuses
intro node ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payload⊢ (result.applyNodeFact state).output node = some value → ((result.applyNodeFact state).status node).mayHaveOutput ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(result.applyNodeFact state).output node = some value⊢ ((result.applyNodeFact state).status node).mayHaveOutput
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(result.applyNodeFact state).output node = some valuehNode:node = result.node⊢ ((result.applyNodeFact state).status node).mayHaveOutputν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(result.applyNodeFact state).output node = some valuehNode:¬node = result.node⊢ ((result.applyNodeFact state).status node).mayHaveOutput
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(result.applyNodeFact state).output node = some valuehNode:node = result.node⊢ ((result.applyNodeFact state).status node).mayHaveOutput ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesvalue:payloadhOutput:(result.applyNodeFact state).output result.node = some value⊢ ((result.applyNodeFact state).status result.node).mayHaveOutput
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesvalue:payloadhOutput:result.outcome.output = some value⊢ result.outcome.status.mayHaveOutput
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(result.applyNodeFact state).output node = some valuehNode:¬node = result.node⊢ ((result.applyNodeFact state).status node).mayHaveOutput have hOriginalOutput : state.output node = some value := ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatuses⊢ (result.applyNodeFact state).outputsRespectStatuses
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsRespectStatusesnode:νvalue:payloadhOutput:(result.applyNodeFact state).output node = some valuehNode:¬node = result.nodehOriginalOutput:state.output node = some valuehMayHaveOutput:(state.status node).mayHaveOutput⊢ ((result.applyNodeFact state).status node).mayHaveOutput
All goals completed! 🐙
applyNodeFact_preserves_outputsCompleteForStatuses preserves required outputs.
theorem applyNodeFact_preserves_outputsCompleteForStatuses [DecidableEq ν]
(result : NodeResult ν payload)
(state : GraphState ν payload)
(hOutputs : GraphState.outputsCompleteForStatuses state) :
GraphState.outputsCompleteForStatuses (applyNodeFact result state) := ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuses⊢ (result.applyNodeFact state).outputsCompleteForStatuses
intro node ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((result.applyNodeFact state).status node).requiresOutput⊢ ∃ value, (result.applyNodeFact state).output node = some value
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((result.applyNodeFact state).status node).requiresOutputhNode:node = result.node⊢ ∃ value, (result.applyNodeFact state).output node = some valueν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((result.applyNodeFact state).status node).requiresOutputhNode:¬node = result.node⊢ ∃ value, (result.applyNodeFact state).output node = some value
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((result.applyNodeFact state).status node).requiresOutputhNode:node = result.node⊢ ∃ value, (result.applyNodeFact state).output node = some value ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutput⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
cases hOutcome : result.outcome with
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputvalue:payloadhOutcome:result.outcome = NodeOutcome.succeeded value⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
exact ⟨value, ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputvalue:payloadhOutcome:result.outcome = NodeOutcome.succeeded value⊢ (result.applyNodeFact state).output result.node = some value All goals completed! 🐙⟩
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputhOutcome:result.outcome = NodeOutcome.skipped⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputhOutcome:result.outcome = NodeOutcome.suspended⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputhOutcome:result.outcome = NodeOutcome.failed⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputhOutcome:result.outcome = NodeOutcome.timedOut⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputhOutcome:result.outcome = NodeOutcome.cancelled⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputhOutcome:result.outcome = NodeOutcome.shutdown⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputhOutcome:result.outcome = NodeOutcome.runCancelled⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputvalue:payloadhOutcome:result.outcome = NodeOutcome.rewritten value⊢ ∃ value, (result.applyNodeFact state).output result.node = some value
exact ⟨value, ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshRequiresOutput:((result.applyNodeFact state).status result.node).requiresOutputvalue:payloadhOutcome:result.outcome = NodeOutcome.rewritten value⊢ (result.applyNodeFact state).output result.node = some value All goals completed! 🐙⟩
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((result.applyNodeFact state).status node).requiresOutputhNode:¬node = result.node⊢ ∃ value, (result.applyNodeFact state).output node = some value have hOriginalRequires : NodeStatus.requiresOutput (state.status node) := ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuses⊢ (result.applyNodeFact state).outputsCompleteForStatuses
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((result.applyNodeFact state).status node).requiresOutputhNode:¬node = result.nodehOriginalRequires:(state.status node).requiresOutputvalue:payloadhOutput:state.output node = some value⊢ ∃ value, (result.applyNodeFact state).output node = some value
exact ⟨value, ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatusesnode:νhRequiresOutput:((result.applyNodeFact state).status node).requiresOutputhNode:¬node = result.nodehOriginalRequires:(state.status node).requiresOutputvalue:payloadhOutput:state.output node = some value⊢ (result.applyNodeFact state).output node = some value All goals completed! 🐙⟩
applyNodeFact_preserves_noRunning preserves the absence of running nodes.
theorem applyNodeFact_preserves_noRunning [DecidableEq ν]
(result : NodeResult ν payload)
(state : GraphState ν payload)
(hNoRunning : GraphState.noRunningNodes state) :
GraphState.noRunningNodes (applyNodeFact result state) := ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhNoRunning:state.noRunningNodes⊢ (result.applyNodeFact state).noRunningNodes
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:ν⊢ (result.applyNodeFact state).status node ≠ NodeStatus.running
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhNode:node = result.node⊢ (result.applyNodeFact state).status node ≠ NodeStatus.runningν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhNode:¬node = result.node⊢ (result.applyNodeFact state).status node ≠ NodeStatus.running
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhNode:node = result.node⊢ (result.applyNodeFact state).status node ≠ NodeStatus.running ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhNoRunning:state.noRunningNodes⊢ (result.applyNodeFact state).status result.node ≠ NodeStatus.running
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νresult:NodeResult ν payloadstate:GraphState ν payloadhNoRunning:state.noRunningNodesnode:νhNode:¬node = result.node⊢ (result.applyNodeFact state).status node ≠ NodeStatus.running All goals completed! 🐙
applyNodeFact_preserves_causalHistoryClosed preserves causal history for admissible facts.
theorem applyNodeFact_preserves_causalHistoryClosed [DecidableEq ν]
(G : DAG ν)
(result : NodeResult ν payload)
(state : GraphState ν payload)
(hCausal : CausalHistoryClosed G state)
(hResult : Admissible G state result) :
CausalHistoryClosed G (applyNodeFact result state) := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state result⊢ CausalHistoryClosed G (result.applyNodeFact state)
classical
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.node⊢ CausalHistoryClosed G (result.applyNodeFact state)
intro node ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessors⊢ ∀ (predecessor : ν), G.reaches predecessor node → ((result.applyNodeFact state).status predecessor).terminal ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:ν⊢ G.reaches predecessor node → ((result.applyNodeFact state).status predecessor).terminal ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor node⊢ ((result.applyNodeFact state).status predecessor).terminal
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:node = result.node⊢ ((result.applyNodeFact state).status predecessor).terminalν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:¬node = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:node = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodepredecessor:νhUnblocks:((result.applyNodeFact state).status result.node).unblocksSuccessorshReach:G.reaches predecessor result.node⊢ ((result.applyNodeFact state).status predecessor).terminal
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodepredecessor:νhUnblocks:((result.applyNodeFact state).status result.node).unblocksSuccessorshReach:G.reaches predecessor result.nodehPred:predecessor = result.node⊢ ((result.applyNodeFact state).status predecessor).terminalν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodepredecessor:νhUnblocks:((result.applyNodeFact state).status result.node).unblocksSuccessorshReach:G.reaches predecessor result.nodehPred:¬predecessor = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodepredecessor:νhUnblocks:((result.applyNodeFact state).status result.node).unblocksSuccessorshReach:G.reaches predecessor result.nodehPred:predecessor = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodehUnblocks:((result.applyNodeFact state).status result.node).unblocksSuccessorshReach:G.reaches result.node result.node⊢ ((result.applyNodeFact state).status result.node).terminal
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodepredecessor:νhUnblocks:((result.applyNodeFact state).status result.node).unblocksSuccessorshReach:G.reaches predecessor result.nodehPred:¬predecessor = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodepredecessor:νhUnblocks:((result.applyNodeFact state).status result.node).unblocksSuccessorshReach:G.reaches predecessor result.nodehPred:¬predecessor = result.nodehOriginalTerminal:(state.status predecessor).terminal⊢ ((result.applyNodeFact state).status predecessor).terminal
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:¬node = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal have hOriginalUnblocks : NodeStatus.unblocksSuccessors (state.status node) := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state result⊢ CausalHistoryClosed G (result.applyNodeFact state)
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:¬node = result.nodehOriginalUnblocks:(state.status node).unblocksSuccessorshPred:predecessor = result.node⊢ ((result.applyNodeFact state).status predecessor).terminalν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:¬node = result.nodehOriginalUnblocks:(state.status node).unblocksSuccessorshPred:¬predecessor = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:¬node = result.nodehOriginalUnblocks:(state.status node).unblocksSuccessorshPred:predecessor = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorshNode:¬node = result.nodehOriginalUnblocks:(state.status node).unblocksSuccessorshReach:G.reaches result.node node⊢ ((result.applyNodeFact state).status result.node).terminal
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorshNode:¬node = result.nodehOriginalUnblocks:(state.status node).unblocksSuccessorshReach:G.reaches result.node nodehOriginalTerminal:(state.status result.node).terminal⊢ ((result.applyNodeFact state).status result.node).terminal
have hPendingTerminal : NodeStatus.terminal NodeStatus.pending := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state result⊢ CausalHistoryClosed G (result.applyNodeFact state)
All goals completed! 🐙
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:¬node = result.nodehOriginalUnblocks:(state.status node).unblocksSuccessorshPred:¬predecessor = result.node⊢ ((result.applyNodeFact state).status predecessor).terminal ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthReady:Ready G state result.nodenode:νhUnblocks:((result.applyNodeFact state).status node).unblocksSuccessorspredecessor:νhReach:G.reaches predecessor nodehNode:¬node = result.nodehOriginalUnblocks:(state.status node).unblocksSuccessorshPred:¬predecessor = result.nodehOriginalTerminal:(state.status predecessor).terminal⊢ ((result.applyNodeFact state).status predecessor).terminal
All goals completed! 🐙Frontier-Fold Accumulation
applyNodeFacts results state folds node-local facts in list order.
def applyNodeFacts [DecidableEq ν]
(results : List (NodeResult ν payload))
(state : GraphState ν payload) : GraphState ν payload :=
results.foldl (fun current result => applyNodeFact result current) state
AllAdmissibleFold G state results requires each folded fact to be frontier-admissible.
def AllAdmissibleFold [DecidableEq ν]
(G : DAG ν) : GraphState ν payload → List (NodeResult ν payload) → Prop
| _state, [] => True
| state, result :: rest =>
Admissible G state result ∧
AllAdmissibleFold G (applyNodeFact result state) rest
applyNodeFacts_preserves_topologyDomain preserves off-topology absence.
theorem applyNodeFacts_preserves_topologyDomain [DecidableEq ν]
(G : DAG ν)
(results : List (NodeResult ν payload))
(state : GraphState ν payload)
(hDomain : GraphState.topologyDomain G state)
(hResults : AllAdmissibleFold G state results) :
GraphState.topologyDomain G (applyNodeFacts results state) := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresults:List (NodeResult ν payload)state:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResults:AllAdmissibleFold G state results⊢ GraphState.topologyDomain G (applyNodeFacts results state)
induction results generalizing state with
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νstate:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResults:AllAdmissibleFold G state []⊢ GraphState.topologyDomain G (applyNodeFacts [] state) All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
GraphState.topologyDomain G state →
AllAdmissibleFold G state rest → GraphState.topologyDomain G (applyNodeFacts rest state)state:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResults:AllAdmissibleFold G state (result :: rest)⊢ GraphState.topologyDomain G (applyNodeFacts (result :: rest) state)
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
GraphState.topologyDomain G state →
AllAdmissibleFold G state rest → GraphState.topologyDomain G (applyNodeFacts rest state)state:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) rest⊢ GraphState.topologyDomain G (applyNodeFacts (result :: rest) state)
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
GraphState.topologyDomain G state →
AllAdmissibleFold G state rest → GraphState.topologyDomain G (applyNodeFacts rest state)state:GraphState ν payloadhDomain:GraphState.topologyDomain G statehResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) resthStep:GraphState.topologyDomain G (result.applyNodeFact state)⊢ GraphState.topologyDomain G (applyNodeFacts (result :: rest) state)
All goals completed! 🐙
applyNodeFacts_preserves_outputsRespectStatuses preserves output ownership.
theorem applyNodeFacts_preserves_outputsRespectStatuses [DecidableEq ν]
(G : DAG ν)
(results : List (NodeResult ν payload))
(state : GraphState ν payload)
(hOutputs : GraphState.outputsRespectStatuses state)
(hResults : AllAdmissibleFold G state results) :
GraphState.outputsRespectStatuses (applyNodeFacts results state) := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresults:List (NodeResult ν payload)state:GraphState ν payloadhOutputs:state.outputsRespectStatuseshResults:AllAdmissibleFold G state results⊢ (applyNodeFacts results state).outputsRespectStatuses
induction results generalizing state with
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νstate:GraphState ν payloadhOutputs:state.outputsRespectStatuseshResults:AllAdmissibleFold G state []⊢ (applyNodeFacts [] state).outputsRespectStatuses All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.outputsRespectStatuses → AllAdmissibleFold G state rest → (applyNodeFacts rest state).outputsRespectStatusesstate:GraphState ν payloadhOutputs:state.outputsRespectStatuseshResults:AllAdmissibleFold G state (result :: rest)⊢ (applyNodeFacts (result :: rest) state).outputsRespectStatuses
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.outputsRespectStatuses → AllAdmissibleFold G state rest → (applyNodeFacts rest state).outputsRespectStatusesstate:GraphState ν payloadhOutputs:state.outputsRespectStatuses_hResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) rest⊢ (applyNodeFacts (result :: rest) state).outputsRespectStatuses
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.outputsRespectStatuses → AllAdmissibleFold G state rest → (applyNodeFacts rest state).outputsRespectStatusesstate:GraphState ν payloadhOutputs:state.outputsRespectStatuses_hResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) resthStep:(result.applyNodeFact state).outputsRespectStatuses⊢ (applyNodeFacts (result :: rest) state).outputsRespectStatuses
All goals completed! 🐙
applyNodeFacts_preserves_outputsCompleteForStatuses preserves required outputs.
theorem applyNodeFacts_preserves_outputsCompleteForStatuses [DecidableEq ν]
(G : DAG ν)
(results : List (NodeResult ν payload))
(state : GraphState ν payload)
(hOutputs : GraphState.outputsCompleteForStatuses state)
(hResults : AllAdmissibleFold G state results) :
GraphState.outputsCompleteForStatuses (applyNodeFacts results state) := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresults:List (NodeResult ν payload)state:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshResults:AllAdmissibleFold G state results⊢ (applyNodeFacts results state).outputsCompleteForStatuses
induction results generalizing state with
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshResults:AllAdmissibleFold G state []⊢ (applyNodeFacts [] state).outputsCompleteForStatuses All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.outputsCompleteForStatuses →
AllAdmissibleFold G state rest → (applyNodeFacts rest state).outputsCompleteForStatusesstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuseshResults:AllAdmissibleFold G state (result :: rest)⊢ (applyNodeFacts (result :: rest) state).outputsCompleteForStatuses
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.outputsCompleteForStatuses →
AllAdmissibleFold G state rest → (applyNodeFacts rest state).outputsCompleteForStatusesstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuses_hResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) rest⊢ (applyNodeFacts (result :: rest) state).outputsCompleteForStatuses
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.outputsCompleteForStatuses →
AllAdmissibleFold G state rest → (applyNodeFacts rest state).outputsCompleteForStatusesstate:GraphState ν payloadhOutputs:state.outputsCompleteForStatuses_hResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) resthStep:(result.applyNodeFact state).outputsCompleteForStatuses⊢ (applyNodeFacts (result :: rest) state).outputsCompleteForStatuses
All goals completed! 🐙
applyNodeFacts_preserves_noRunning preserves the absence of running nodes.
theorem applyNodeFacts_preserves_noRunning [DecidableEq ν]
(G : DAG ν)
(results : List (NodeResult ν payload))
(state : GraphState ν payload)
(hNoRunning : GraphState.noRunningNodes state)
(hResults : AllAdmissibleFold G state results) :
GraphState.noRunningNodes (applyNodeFacts results state) := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresults:List (NodeResult ν payload)state:GraphState ν payloadhNoRunning:state.noRunningNodeshResults:AllAdmissibleFold G state results⊢ (applyNodeFacts results state).noRunningNodes
induction results generalizing state with
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νstate:GraphState ν payloadhNoRunning:state.noRunningNodeshResults:AllAdmissibleFold G state []⊢ (applyNodeFacts [] state).noRunningNodes All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.noRunningNodes → AllAdmissibleFold G state rest → (applyNodeFacts rest state).noRunningNodesstate:GraphState ν payloadhNoRunning:state.noRunningNodeshResults:AllAdmissibleFold G state (result :: rest)⊢ (applyNodeFacts (result :: rest) state).noRunningNodes
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.noRunningNodes → AllAdmissibleFold G state rest → (applyNodeFacts rest state).noRunningNodesstate:GraphState ν payloadhNoRunning:state.noRunningNodes_hResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) rest⊢ (applyNodeFacts (result :: rest) state).noRunningNodes
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
state.noRunningNodes → AllAdmissibleFold G state rest → (applyNodeFacts rest state).noRunningNodesstate:GraphState ν payloadhNoRunning:state.noRunningNodes_hResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) resthStep:(result.applyNodeFact state).noRunningNodes⊢ (applyNodeFacts (result :: rest) state).noRunningNodes
All goals completed! 🐙
applyNodeFacts_preserves_causalHistoryClosed preserves causal history.
theorem applyNodeFacts_preserves_causalHistoryClosed [DecidableEq ν]
(G : DAG ν)
(results : List (NodeResult ν payload))
(state : GraphState ν payload)
(hCausal : CausalHistoryClosed G state)
(hResults : AllAdmissibleFold G state results) :
CausalHistoryClosed G (applyNodeFacts results state) := ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresults:List (NodeResult ν payload)state:GraphState ν payloadhCausal:CausalHistoryClosed G statehResults:AllAdmissibleFold G state results⊢ CausalHistoryClosed G (applyNodeFacts results state)
induction results generalizing state with
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νstate:GraphState ν payloadhCausal:CausalHistoryClosed G statehResults:AllAdmissibleFold G state []⊢ CausalHistoryClosed G (applyNodeFacts [] state) All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
CausalHistoryClosed G state → AllAdmissibleFold G state rest → CausalHistoryClosed G (applyNodeFacts rest state)state:GraphState ν payloadhCausal:CausalHistoryClosed G statehResults:AllAdmissibleFold G state (result :: rest)⊢ CausalHistoryClosed G (applyNodeFacts (result :: rest) state)
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
CausalHistoryClosed G state → AllAdmissibleFold G state rest → CausalHistoryClosed G (applyNodeFacts rest state)state:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) rest⊢ CausalHistoryClosed G (applyNodeFacts (result :: rest) state)
ν:Type upayload:Type vinst✝:DecidableEq νG:DAG νresult:NodeResult ν payloadrest:List (NodeResult ν payload)ih:∀ (state : GraphState ν payload),
CausalHistoryClosed G state → AllAdmissibleFold G state rest → CausalHistoryClosed G (applyNodeFacts rest state)state:GraphState ν payloadhCausal:CausalHistoryClosed G statehResult:Admissible G state resulthRest:AllAdmissibleFold G (result.applyNodeFact state) resthStep:CausalHistoryClosed G (result.applyNodeFact state)⊢ CausalHistoryClosed G (applyNodeFacts (result :: rest) state)
All goals completed! 🐙Disjoint-Key Accumulation
applyNodeFact_comm proves facts for distinct nodes commute.
theorem applyNodeFact_comm [DecidableEq ν]
(r1 r2 : NodeResult ν payload)
(state : GraphState ν payload)
(hDistinct : r1.node ≠ r2.node) :
applyNodeFact r1 (applyNodeFact r2 state) =
applyNodeFact r2 (applyNodeFact r1 state) := ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.node⊢ r1.applyNodeFact (r2.applyNodeFact state) = r2.applyNodeFact (r1.applyNodeFact state)
have hDistinctSymm : r2.node ≠ r1.node := ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.node⊢ r1.applyNodeFact (r2.applyNodeFact state) = r2.applyNodeFact (r1.applyNodeFact state)
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehEq:r2.node = r1.node⊢ False
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:ν⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status nν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payload⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:ν⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:n = r1.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status nν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:¬n = r1.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:n = r1.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:n = r1.nodeh2:n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status nν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:n = r1.nodeh2:¬n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:n = r1.nodeh2:n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n exact False.elim (hDistinct (ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:n = r1.nodeh2:n = r2.node⊢ r1.node = r2.node All goals completed! 🐙))
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:n = r1.nodeh2:¬n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:¬n = r1.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:¬n = r1.nodeh2:n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status nν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:¬n = r1.nodeh2:¬n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:¬n = r1.nodeh2:n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νh1:¬n = r1.nodeh2:¬n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).status n = (r2.applyNodeFact (r1.applyNodeFact state)).status n All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payload⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:n = r1.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:¬n = r1.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:n = r1.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:n = r1.nodeh2:n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:n = r1.nodeh2:¬n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:n = r1.nodeh2:n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ exact False.elim (hDistinct (ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:n = r1.nodeh2:n = r2.node⊢ r1.node = r2.node All goals completed! 🐙))
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:n = r1.nodeh2:¬n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:¬n = r1.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:¬n = r1.nodeh2:n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:¬n = r1.nodeh2:¬n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:¬n = r1.nodeh2:n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νr1:NodeResult ν payloadr2:NodeResult ν payloadstate:GraphState ν payloadhDistinct:r1.node ≠ r2.nodehDistinctSymm:r2.node ≠ r1.noden:νa✝:payloadh1:¬n = r1.nodeh2:¬n = r2.node⊢ (r1.applyNodeFact (r2.applyNodeFact state)).output n = some a✝ ↔
(r2.applyNodeFact (r1.applyNodeFact state)).output n = some a✝ All goals completed! 🐙
applyNodeFacts_perm_invariant lifts disjoint-key commutativity to fact folds.
theorem applyNodeFacts_perm_invariant [DecidableEq ν]
{left right : List (NodeResult ν payload)}
(hPerm : left.Perm right)
(hDistinct : left.Pairwise (fun first second => first.node ≠ second.node))
(state : GraphState ν payload) :
applyNodeFacts left state = applyNodeFacts right state := ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payload⊢ applyNodeFacts left state = applyNodeFacts right state
ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payload⊢ List.foldl (fun current result => result.applyNodeFact current) state left =
List.foldl (fun current result => result.applyNodeFact current) state right
ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payload⊢ ∀ x ∈ left,
∀ y ∈ left, ∀ (z : GraphState ν payload), y.applyNodeFact (x.applyNodeFact z) = x.applyNodeFact (y.applyNodeFact z)
intro first ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ left⊢ ∀ y ∈ left,
∀ (z : GraphState ν payload), y.applyNodeFact (first.applyNodeFact z) = first.applyNodeFact (y.applyNodeFact z) ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payload⊢ second ∈ left →
∀ (z : GraphState ν payload),
second.applyNodeFact (first.applyNodeFact z) = first.applyNodeFact (second.applyNodeFact z) ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ left⊢ ∀ (z : GraphState ν payload),
second.applyNodeFact (first.applyNodeFact z) = first.applyNodeFact (second.applyNodeFact z) ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payload⊢ second.applyNodeFact (first.applyNodeFact current) = first.applyNodeFact (second.applyNodeFact current)
ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payloadhSame:first = second⊢ second.applyNodeFact (first.applyNodeFact current) = first.applyNodeFact (second.applyNodeFact current)ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payloadhSame:¬first = second⊢ second.applyNodeFact (first.applyNodeFact current) = first.applyNodeFact (second.applyNodeFact current)
ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payloadhSame:first = second⊢ second.applyNodeFact (first.applyNodeFact current) = first.applyNodeFact (second.applyNodeFact current) ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftcurrent:GraphState ν payloadhSecond:first ∈ left⊢ first.applyNodeFact (first.applyNodeFact current) = first.applyNodeFact (first.applyNodeFact current)
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payloadhSame:¬first = second⊢ second.applyNodeFact (first.applyNodeFact current) = first.applyNodeFact (second.applyNodeFact current) have hSymm :
Symmetric (fun first second : NodeResult ν payload => first.node ≠ second.node) := ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payload⊢ applyNodeFacts left state = applyNodeFacts right state
intro a ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payloadhSame:¬first = seconda:NodeResult ν payloadb:NodeResult ν payload⊢ (fun first second => first.node ≠ second.node) a b → (fun first second => first.node ≠ second.node) b a ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payloadhSame:¬first = seconda:NodeResult ν payloadb:NodeResult ν payloadhDistinctNodes:a.node ≠ b.node⊢ b.node ≠ a.node ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payloadhSame:¬first = seconda:NodeResult ν payloadb:NodeResult ν payloadhDistinctNodes:a.node ≠ b.nodehEq:b.node = a.node⊢ False
All goals completed! 🐙
ν:Type upayload:Type vinst✝:DecidableEq νleft:List (NodeResult ν payload)right:List (NodeResult ν payload)hPerm:left.Perm righthDistinct:List.Pairwise (fun first second => first.node ≠ second.node) leftstate:GraphState ν payloadfirst:NodeResult ν payloadhFirst:first ∈ leftsecond:NodeResult ν payloadhSecond:second ∈ leftcurrent:GraphState ν payloadhSame:¬first = secondhSymm:Symmetric fun first second => first.node ≠ second.nodehDistinctNodes:first.node ≠ second.node⊢ second.applyNodeFact (first.applyNodeFact current) = first.applyNodeFact (second.applyNodeFact current)
All goals completed! 🐙end NodeResultend Cortex.Pulse