/- Copyright (c) 2022 Mac Malone. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mac Malone -/ import Lake.Util.Name namespace Lake /-- The type of keys in the Lake build store. -/ structure BuildKey where package? : Option WfName target? : Option WfName facet : WfName deriving Inhabited, Repr, DecidableEq, Hashable namespace BuildKey @[inline] def hasPackage (self : BuildKey) : Bool := self.package? ≠ none @[simp] theorem hasPackage_mk : BuildKey.hasPackage ⟨some p, x, f⟩ := by simp [BuildKey.hasPackage] @[inline] def package (self : BuildKey) (h : self.hasPackage) : WfName := match mh:self.package? with | some n => n | none => absurd mh <| by unfold hasPackage at h exact of_decide_eq_true h @[inline] def hasTarget (self : BuildKey) : Bool := self.target? ≠ none @[simp] theorem hasTarget_mk : BuildKey.hasTarget ⟨x, some t, f⟩ := by simp [BuildKey.hasTarget] @[inline] def target (self : BuildKey) (h : self.hasTarget) : WfName := match mh:self.target? with | some n => n | none => absurd mh <| by unfold hasTarget at h exact of_decide_eq_true h @[inline] def isModuleKey (self : BuildKey) : Bool := self.package? = none ∧ self.hasTarget @[simp] theorem isModuleKey_mk : BuildKey.isModuleKey ⟨none, some m, f⟩ := by simp [BuildKey.isModuleKey] @[simp] theorem not_isModuleKey_pkg : ¬BuildKey.isModuleKey ⟨some pkg, x, f⟩ := by simp [BuildKey.isModuleKey] @[inline] def module (self : BuildKey) (h : self.isModuleKey) : WfName := self.target <| by unfold isModuleKey at h exact of_decide_eq_true h |>.2 @[inline] def isPackageKey (self : BuildKey) : Bool := self.hasPackage ∧ self.target? = none @[simp] theorem isPackageKey_mk : BuildKey.isPackageKey ⟨some p, none, f⟩ := by simp [BuildKey.isPackageKey] @[simp] theorem not_isPackageKey_target : ¬BuildKey.isPackageKey ⟨o, some t, f⟩ := by simp [BuildKey.isPackageKey] @[inline] def isTargetKey (self : BuildKey) : Bool := self.hasPackage ∧ self.hasTarget @[simp] theorem isTargetKey_mk : BuildKey.isTargetKey ⟨some p, some t, f⟩ := by simp [BuildKey.isTargetKey] protected def toString : (self : BuildKey) → String | ⟨some p, none, f⟩ => s!"@{p}:{f}" | ⟨none, some m, f⟩ => s!"+{m}:{f}" | ⟨some p, some t, f⟩ => s!"{p}/{t}:{f}" | ⟨none, none, f⟩ => s!":{f}" instance : ToString BuildKey := ⟨(·.toString)⟩ def quickCmp (k k' : BuildKey) := match Option.compareWith WfName.quickCmp k.package? k'.package? with | .eq => match Option.compareWith WfName.quickCmp k.target? k'.target? with | .eq => k.facet.quickCmp k'.facet | ord => ord | ord => ord theorem eq_of_quickCmp : {k k' : _} → quickCmp k k' = Ordering.eq → k = k' := by intro ⟨p, t, f⟩ ⟨p', t', f'⟩ unfold quickCmp simp only [] split next p_eq => split next t_eq => intro f_eq have p_eq := eq_of_cmp p_eq have t_eq := eq_of_cmp t_eq have f_eq := eq_of_cmp f_eq simp only [p_eq, t_eq, f_eq] next => intros; contradiction next => intros; contradiction instance : EqOfCmp BuildKey quickCmp where eq_of_cmp := eq_of_quickCmp end BuildKey -- ## Subtypes /-- The type of build keys for modules. -/ structure ModuleBuildKey (fixedFacet : WfName) extends BuildKey where is_module_key : toBuildKey.isModuleKey = true facet_eq_fixed : toBuildKey.facet = fixedFacet instance : Coe (ModuleBuildKey f) BuildKey := ⟨(·.toBuildKey)⟩ @[inline] def BuildKey.toModuleKey (self : BuildKey) (h : self.isModuleKey) : ModuleBuildKey self.facet := ⟨self, h, rfl⟩ @[inline] def ModuleBuildKey.module (self : ModuleBuildKey f) : WfName := self.toBuildKey.module self.is_module_key /-- The type of build keys for packages. -/ structure PackageBuildKey (fixedFacet : WfName) extends BuildKey where is_package_key : toBuildKey.isPackageKey = true facet_eq_fixed : toBuildKey.facet = fixedFacet instance : Coe (PackageBuildKey f) BuildKey := ⟨(·.toBuildKey)⟩ @[inline] def BuildKey.toPackageKey (self : BuildKey) (h : self.isPackageKey) : PackageBuildKey self.facet := ⟨self, h, rfl⟩ @[inline] def PackageBuildKey.package (self : PackageBuildKey f) : WfName := self.toBuildKey.package <| by have h := self.is_package_key unfold BuildKey.isPackageKey at h exact (of_decide_eq_true h).1