{-# OPTIONS --safe --cubical #-}
module Spartan6.Netlist.ReadySchedule where
open import Spartan6.Prelude
import Spartan6.Netlist.Provenance as Provenance
import Spartan6.Netlist.Raw as Raw
import Spartan6.Validation.Diagnostic as Diagnostic
import Spartan6.Validation.Raw as Validation
open import Cubical.Data.Nat using (_≡ᵇ_)
open import Cubical.Data.Bool.Base using (Bool→Type)
open import Cubical.Data.Nat.Properties using (≡ᵇ→≡)
record Operation : Type₀ where
constructor operation
field
operationId : Provenance.OccurrenceId
requiredNets : List Raw.NetId
producedNets : List Raw.NetId
open Operation public
sameOccurrence : Provenance.OccurrenceId → Provenance.OccurrenceId → Bool
sameOccurrence (Provenance.occurrenceId left)
(Provenance.occurrenceId right) = left ≡ᵇ right
allAvailable : List Raw.NetId → List Raw.NetId → Bool
allAvailable []ᴸ available = true
allAvailable (required ∷ᴸ requireds) available =
Validation.containsNet required available
and allAvailable requireds available
Ready : List Raw.NetId → Operation → Type₀
Ready available item = allAvailable (requiredNets item) available ≡ true
addProduced : Operation → List Raw.NetId → List Raw.NetId
addProduced item available = producedNets item ++ᴸ available
data Removed (item : Operation) : List Operation → List Operation → Type₀ where
removeHere : ∀ {items} → Removed item (item ∷ᴸ items) items
removeThere : ∀ {other items remaining}
→ Removed item items remaining
→ Removed item (other ∷ᴸ items) (other ∷ᴸ remaining)
record Selection
(identifier : Provenance.OccurrenceId)
(source : List Operation) : Type₀ where
field
selected : Operation
remaining : List Operation
selectedId : operationId selected ≡ identifier
selectedRemoved : Removed selected source remaining
open Selection public
prependSelection : ∀ identifier skipped {items}
→ Selection identifier items → Selection identifier (skipped ∷ᴸ items)
prependSelection identifier skipped selection = record
{ selected = selected selection
; remaining = skipped ∷ᴸ remaining selection
; selectedId = selectedId selection
; selectedRemoved = removeThere (selectedRemoved selection)
}
selectById : (identifier : Provenance.OccurrenceId)
→ (source : List Operation) → Maybe (Selection identifier source)
selectById identifier []ᴸ = nothing
selectById identifier (item ∷ᴸ items) with
sameOccurrence (operationId item) identifier UsingEq
... | true , same-path = just record
{ selected = item
; remaining = items
; selectedId = occurrence-equality item identifier same-path
; selectedRemoved = removeHere
}
where
occurrence-equality : (item : Operation)
→ (identifier : Provenance.OccurrenceId)
→ sameOccurrence (operationId item) identifier ≡ true
→ operationId item ≡ identifier
occurrence-equality
(operation (Provenance.occurrenceId left) required produced)
(Provenance.occurrenceId right) equality =
cong Provenance.occurrenceId
(≡ᵇ→≡ (subst Bool→Type (sym equality) tt))
... | false , same-path with selectById identifier items
... | nothing = nothing
... | just selection = just (prependSelection identifier item selection)
data ScheduleTrace :
List Raw.NetId → List Operation → List Operation
→ List Raw.NetId → Type₀ where
scheduleDone : ∀ {available}
→ ScheduleTrace available []ᴸ []ᴸ available
scheduleNext : ∀ {available source item remaining scheduled final}
→ Removed item source remaining
→ Ready available item
→ ScheduleTrace (addProduced item available)
remaining scheduled final
→ ScheduleTrace available source (item ∷ᴸ scheduled) final
record Scheduled (initial : List Raw.NetId) (source : List Operation) : Type₀ where
constructor scheduled
field
scheduledOperations : List Operation
finalAvailable : List Raw.NetId
schedulingTrace :
ScheduleTrace initial source scheduledOperations finalAvailable
open Scheduled public
singleton : Diagnostic.Diagnostic → Diagnostic.Diagnostics
singleton problem = problem ∷ᴸ []ᴸ
deadlockDiagnostic invalidHintDiagnostic blockedHintDiagnostic :
Diagnostic.Diagnostic
deadlockDiagnostic =
Diagnostic.diagnostic Diagnostic.combinationalLoop Diagnostic.reject
"readiness scheduler" "a complete ready occurrence certificate"
"pending operations after the certificate ended"
"All permanent failures were excluded before scheduling; remaining work is a dependency deadlock or an incomplete certificate."
invalidHintDiagnostic =
Diagnostic.diagnostic Diagnostic.malformedImport Diagnostic.reject
"schedule certificate" "each source occurrence exactly once"
"an unknown or repeated occurrence identifier"
"The certificate checker never invents an operation or assigns precedence to a duplicate identifier."
blockedHintDiagnostic =
Diagnostic.diagnostic Diagnostic.undrivenInput Diagnostic.reject
"schedule certificate" "all required nets available at this step"
"a temporarily blocked selected occurrence"
"A certificate must order operations by readiness; another valid order may still exist."
continueScheduled : ∀ {available source identifier}
→ (selection : Selection identifier source)
→ Ready available (selected selection)
→ Diagnostic.CheckResult
(Scheduled
(addProduced (selected selection) available)
(remaining selection))
→ Diagnostic.CheckResult (Scheduled available source)
continueScheduled selection ready (Diagnostic.rejected diagnostics) =
Diagnostic.rejected diagnostics
continueScheduled selection ready (Diagnostic.accepted suffix) =
Diagnostic.accepted
(scheduled
(selected selection ∷ᴸ scheduledOperations suffix)
(finalAvailable suffix)
(scheduleNext
(selectedRemoved selection) ready (schedulingTrace suffix)))
checkSchedule : (available : List Raw.NetId)
→ (source : List Operation)
→ List Provenance.OccurrenceId
→ Diagnostic.CheckResult (Scheduled available source)
checkSchedule available []ᴸ []ᴸ =
Diagnostic.accepted (scheduled []ᴸ available scheduleDone)
checkSchedule available (item ∷ᴸ items) []ᴸ =
Diagnostic.rejected (singleton deadlockDiagnostic)
checkSchedule available []ᴸ (identifier ∷ᴸ identifiers) =
Diagnostic.rejected (singleton invalidHintDiagnostic)
checkSchedule available source (identifier ∷ᴸ identifiers) with
selectById identifier source
... | nothing = Diagnostic.rejected (singleton invalidHintDiagnostic)
... | just selection with
allAvailable (requiredNets (selected selection)) available UsingEq
... | false , ready-path =
Diagnostic.rejected (singleton blockedHintDiagnostic)
... | true , ready-path with
checkSchedule
(addProduced (selected selection) available)
(remaining selection) identifiers
... | suffix = continueScheduled selection ready-path suffix
data RemovalPermutation : List Operation → List Operation → Type₀ where
permutationDone : RemovalPermutation []ᴸ []ᴸ
permutationNext : ∀ {source item remaining scheduled}
→ Removed item source remaining
→ RemovalPermutation remaining scheduled
→ RemovalPermutation source (item ∷ᴸ scheduled)
tracePermutation : ∀ {available source scheduled final}
→ ScheduleTrace available source scheduled final
→ RemovalPermutation source scheduled
tracePermutation scheduleDone = permutationDone
tracePermutation (scheduleNext removed ready rest) =
permutationNext removed (tracePermutation rest)
scheduledPermutation : ∀ {available source}
→ (result : Scheduled available source)
→ RemovalPermutation source (scheduledOperations result)
scheduledPermutation result = tracePermutation (schedulingTrace result)
replayAvailable : List Operation → List Raw.NetId → List Raw.NetId
replayAvailable []ᴸ available = available
replayAvailable (item ∷ᴸ items) available =
replayAvailable items (addProduced item available)
traceReplays : ∀ {available source scheduled final}
→ ScheduleTrace available source scheduled final
→ replayAvailable scheduled available ≡ final
traceReplays scheduleDone = refl
traceReplays (scheduleNext removed ready rest) = traceReplays rest
record ScheduleCost : Type₀ where
constructor scheduleCost
field
readinessChecks : ℕ
handlerExecutions : ℕ
dependencyEvents : ℕ
enqueues : ℕ
nodeConstructions : ℕ
open ScheduleCost public
sumRequired : List Operation → ℕ
sumRequired []ᴸ = 0
sumRequired (item ∷ᴸ items) =
lengthList (requiredNets item) + sumRequired items
checkedCost : ∀ {available source} → Scheduled available source
→ ScheduleCost
checkedCost result = scheduleCost count count edges count count
where
count = lengthList (scheduledOperations result)
edges = sumRequired (scheduledOperations result)
data AcyclicOrder : List Raw.NetId → List Operation → Type₀ where
orderDone : ∀ {available} → AcyclicOrder available []ᴸ
orderNext : ∀ {available source identifier}
→ (selection : Selection identifier source)
→ selectById identifier source ≡ just selection
→ Ready available (selected selection)
→ AcyclicOrder
(addProduced (selected selection) available)
(remaining selection)
→ AcyclicOrder available source
orderHint : ∀ {available source} → AcyclicOrder available source
→ List Provenance.OccurrenceId
orderHint orderDone = []ᴸ
orderHint (orderNext {identifier = identifier} selection found ready rest) =
identifier ∷ᴸ orderHint rest
scheduledFromOrder : ∀ {available source}
→ AcyclicOrder available source → Scheduled available source
scheduledFromOrder orderDone = scheduled []ᴸ _ scheduleDone
scheduledFromOrder
(orderNext selection found ready rest) with scheduledFromOrder rest
... | suffix = scheduled
(selected selection ∷ᴸ scheduledOperations suffix)
(finalAvailable suffix)
(scheduleNext (selectedRemoved selection) ready (schedulingTrace suffix))
acyclic-order-schedules : ∀ {available source}
→ AcyclicOrder available source
→ Scheduled available source
acyclic-order-schedules = scheduledFromOrder