@@ -254,6 +254,113 @@ theorem card_productQuotientRules {Z₁ Z₂ A : Type}
254254 Fintype.card A ^ (Fintype.card Z₁ * Fintype.card Z₂) := by
255255 rw [Fintype.card_fun, Fintype.card_prod]
256256
257+ /--
258+ The reachable image of a product map is contained in the product of the two
259+ reachable component images.
260+ -/
261+ theorem productMap_image_subset_product_images
262+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
263+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
264+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
265+ QuotientImageFinset (productMap Q₁ Q₂) ⊆
266+ (QuotientImageFinset Q₁).product (QuotientImageFinset Q₂) := by
267+ intro z hz
268+ rcases Finset.mem_image.mp hz with ⟨p, _hp, hp⟩
269+ rw [← hp]
270+ exact Finset.mem_product.mpr
271+ ⟨Finset.mem_image.mpr ⟨p.1 , Finset.mem_univ p.1 , rfl⟩,
272+ Finset.mem_image.mpr ⟨p.2 , Finset.mem_univ p.2 , rfl⟩⟩
273+
274+ /--
275+ The reachable image of a product map is exactly the product of the reachable
276+ component images.
277+ -/
278+ theorem productMap_image_eq_product_images
279+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
280+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
281+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
282+ QuotientImageFinset (productMap Q₁ Q₂) =
283+ (QuotientImageFinset Q₁).product (QuotientImageFinset Q₂) := by
284+ apply Finset.Subset.antisymm
285+ · exact productMap_image_subset_product_images Q₁ Q₂
286+ · intro z hz
287+ rcases Finset.mem_product.mp hz with ⟨hz₁, hz₂⟩
288+ rcases Finset.mem_image.mp hz₁ with ⟨x, _hx, hx⟩
289+ rcases Finset.mem_image.mp hz₂ with ⟨y, _hy, hy⟩
290+ exact Finset.mem_image.mpr
291+ ⟨(x, y), Finset.mem_univ (x, y), Prod.ext hx hy⟩
292+
293+ /--
294+ The number of reachable product codes is exactly the product of the numbers of
295+ reachable component codes.
296+ -/
297+ theorem productMap_image_card_eq_product_images_card
298+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
299+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
300+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
301+ (QuotientImageFinset (productMap Q₁ Q₂)).card =
302+ (QuotientImageFinset Q₁).card * (QuotientImageFinset Q₂).card := by
303+ rw [productMap_image_eq_product_images Q₁ Q₂]
304+ simp
305+
306+ /--
307+ The number of reachable product codes is bounded by the product of the numbers
308+ of reachable component codes.
309+ -/
310+ theorem productMap_image_card_le_product_images_card
311+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
312+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
313+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
314+ (QuotientImageFinset (productMap Q₁ Q₂)).card ≤
315+ (QuotientImageFinset Q₁).card * (QuotientImageFinset Q₂).card := by
316+ rw [productMap_image_card_eq_product_images_card Q₁ Q₂]
317+
318+ /--
319+ Rules on the reachable product image have search-space size
320+ `|A| ^ |image(productMap Q₁ Q₂)|`.
321+ -/
322+ theorem card_productImageQuotientRules
323+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
324+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
325+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
326+ Fintype.card (QuotientImageBucket (productMap Q₁ Q₂) → A) =
327+ Fintype.card A ^ (QuotientImageFinset (productMap Q₁ Q₂)).card := by
328+ classical
329+ letI : Fintype (QuotientImageBucket (productMap Q₁ Q₂)) :=
330+ Fintype.ofFinset (QuotientImageFinset (productMap Q₁ Q₂)) (by
331+ intro z
332+ constructor <;> intro hz <;> exact hz)
333+ rw [Fintype.card_fun]
334+ congr
335+ simp [QuotientImageBucket]
336+
337+ /--
338+ Rules on the reachable product image have search-space size
339+ `|A| ^ (|image Q₁| * |image Q₂|)`.
340+ -/
341+ theorem card_productImageQuotientRules_eq_product_images
342+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
343+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
344+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
345+ Fintype.card (QuotientImageBucket (productMap Q₁ Q₂) → A) =
346+ Fintype.card A ^
347+ ((QuotientImageFinset Q₁).card * (QuotientImageFinset Q₂).card) := by
348+ rw [card_productImageQuotientRules Q₁ Q₂,
349+ productMap_image_card_eq_product_images_card Q₁ Q₂]
350+
351+ /--
352+ Product-image quotient rules are bounded by assigning labels to every
353+ component-image pair.
354+ -/
355+ theorem card_productImageQuotientRules_le_product_images
356+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
357+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
358+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
359+ Fintype.card (QuotientImageBucket (productMap Q₁ Q₂) → A) ≤
360+ Fintype.card A ^
361+ ((QuotientImageFinset Q₁).card * (QuotientImageFinset Q₂).card) := by
362+ rw [card_productImageQuotientRules_eq_product_images Q₁ Q₂]
363+
257364namespace RuleFactorsThrough
258365
259366/-- Pairing two product-factorized targets is equivalent to factoring both components. -/
@@ -301,6 +408,26 @@ structure ComparisonObs (Ω₁ Ω₂ : Type) where
301408 second : Ω₂
302409deriving DecidableEq
303410
411+ /-- Finite comparison observations are equivalent to left/right/right triples. -/
412+ def comparisonObsEquivProd (Ω₁ Ω₂ : Type ) :
413+ ComparisonObs Ω₁ Ω₂ ≃ Ω₁ × Ω₂ × Ω₂ where
414+ toFun c := (c.left, c.first, c.second)
415+ invFun x := {
416+ left := x.1
417+ first := x.2 .1
418+ second := x.2 .2
419+ }
420+ left_inv c := by
421+ cases c
422+ rfl
423+ right_inv x := by
424+ cases x
425+ rfl
426+
427+ noncomputable instance comparisonObsFintype {Ω₁ Ω₂ : Type }
428+ [Fintype Ω₁] [Fintype Ω₂] : Fintype (ComparisonObs Ω₁ Ω₂) :=
429+ Fintype.ofEquiv (Ω₁ × Ω₂ × Ω₂) (comparisonObsEquivProd Ω₁ Ω₂).symm
430+
304431/-- Product quotient for a left item and two right items. -/
305432def comparisonMap {Ω₁ Ω₂ Z₁ Z₂ : Type }
306433 (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
@@ -396,4 +523,149 @@ theorem rankByScore_factorsThrough_of_score_factorsThrough
396523 cases c
397524 simp [rankByScore, comparisonMap, hscoreQ]
398525
526+ /-! ## Comparison image bounds -/
527+
528+ /--
529+ The ambient box of reachable comparison codes induced by one left image and two
530+ right images.
531+ -/
532+ def ComparisonImageBox {Ω₁ Ω₂ Z₁ Z₂ : Type }
533+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
534+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) : Finset (ComparisonObs Z₁ Z₂) :=
535+ ((QuotientImageFinset Q₁).product
536+ ((QuotientImageFinset Q₂).product (QuotientImageFinset Q₂))).image
537+ (fun z => {
538+ left := z.1
539+ first := z.2 .1
540+ second := z.2 .2
541+ })
542+
543+ /--
544+ The reachable image of a comparison map is contained in the box of reachable
545+ left/right/right component codes.
546+ -/
547+ theorem comparisonMap_image_subset_imageBox
548+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
549+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
550+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
551+ QuotientImageFinset (comparisonMap Q₁ Q₂) ⊆
552+ ComparisonImageBox Q₁ Q₂ := by
553+ intro z hz
554+ rcases Finset.mem_image.mp hz with ⟨c, _hc, hc⟩
555+ rw [← hc]
556+ unfold ComparisonImageBox
557+ apply Finset.mem_image.mpr
558+ refine ⟨(Q₁ c.left, (Q₂ c.first, Q₂ c.second)), ?_, rfl⟩
559+ exact Finset.mem_product.mpr
560+ ⟨Finset.mem_image.mpr ⟨c.left, Finset.mem_univ c.left, rfl⟩,
561+ Finset.mem_product.mpr
562+ ⟨Finset.mem_image.mpr ⟨c.first, Finset.mem_univ c.first, rfl⟩,
563+ Finset.mem_image.mpr ⟨c.second, Finset.mem_univ c.second, rfl⟩⟩⟩
564+
565+ /--
566+ The reachable image of a comparison map is exactly the box of reachable
567+ left/right/right component codes.
568+ -/
569+ theorem comparisonMap_image_eq_imageBox
570+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
571+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
572+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
573+ QuotientImageFinset (comparisonMap Q₁ Q₂) =
574+ ComparisonImageBox Q₁ Q₂ := by
575+ apply Finset.Subset.antisymm
576+ · exact comparisonMap_image_subset_imageBox Q₁ Q₂
577+ · intro z hz
578+ unfold ComparisonImageBox at hz
579+ rcases Finset.mem_image.mp hz with ⟨p, hp, hpz⟩
580+ rcases Finset.mem_product.mp hp with ⟨hzleft, hzrights⟩
581+ rcases Finset.mem_product.mp hzrights with ⟨hzfirst, hzsecond⟩
582+ rcases Finset.mem_image.mp hzleft with ⟨x, _hxmem, hx⟩
583+ rcases Finset.mem_image.mp hzfirst with ⟨y₁, _hy₁mem, hy₁⟩
584+ rcases Finset.mem_image.mp hzsecond with ⟨y₂, _hy₂mem, hy₂⟩
585+ apply Finset.mem_image.mpr
586+ refine ⟨{ left := x, first := y₁, second := y₂ }, Finset.mem_univ _, ?_⟩
587+ rw [← hpz]
588+ simp [comparisonMap, hx, hy₁, hy₂]
589+
590+ /--
591+ The number of reachable comparison codes is exactly
592+ `|image Q₁| * |image Q₂| * |image Q₂|`.
593+ -/
594+ theorem comparisonMap_image_card_eq_product_images_card
595+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
596+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
597+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
598+ (QuotientImageFinset (comparisonMap Q₁ Q₂)).card =
599+ (QuotientImageFinset Q₁).card *
600+ (QuotientImageFinset Q₂).card * (QuotientImageFinset Q₂).card := by
601+ rw [comparisonMap_image_eq_imageBox Q₁ Q₂]
602+ unfold ComparisonImageBox
603+ rw [Finset.card_image_of_injective]
604+ · simp [mul_assoc]
605+ · intro p₁ p₂ h
606+ exact Prod.ext (congrArg ComparisonObs.left h)
607+ (Prod.ext (congrArg ComparisonObs.first h)
608+ (congrArg ComparisonObs.second h))
609+
610+ /--
611+ The number of reachable comparison codes is bounded by
612+ `|image Q₁| * |image Q₂| * |image Q₂|`.
613+ -/
614+ theorem comparisonMap_image_card_le_product_images_card
615+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
616+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
617+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
618+ (QuotientImageFinset (comparisonMap Q₁ Q₂)).card ≤
619+ (QuotientImageFinset Q₁).card *
620+ (QuotientImageFinset Q₂).card * (QuotientImageFinset Q₂).card := by
621+ rw [comparisonMap_image_card_eq_product_images_card Q₁ Q₂]
622+
623+ /--
624+ Rules on the reachable comparison image have search-space size
625+ `|A| ^ |image(comparisonMap Q₁ Q₂)|`.
626+ -/
627+ theorem card_comparisonImageQuotientRules
628+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
629+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
630+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
631+ Fintype.card (QuotientImageBucket (comparisonMap Q₁ Q₂) → A) =
632+ Fintype.card A ^ (QuotientImageFinset (comparisonMap Q₁ Q₂)).card := by
633+ classical
634+ letI : Fintype (QuotientImageBucket (comparisonMap Q₁ Q₂)) :=
635+ Fintype.ofFinset (QuotientImageFinset (comparisonMap Q₁ Q₂)) (by
636+ intro z
637+ constructor <;> intro hz <;> exact hz)
638+ rw [Fintype.card_fun]
639+ congr
640+ simp [QuotientImageBucket]
641+
642+ /--
643+ Rules on the reachable comparison image have search-space size
644+ `|A| ^ (|image Q₁| * |image Q₂| * |image Q₂|)`.
645+ -/
646+ theorem card_comparisonImageQuotientRules_eq_product_images
647+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
648+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
649+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
650+ Fintype.card (QuotientImageBucket (comparisonMap Q₁ Q₂) → A) =
651+ Fintype.card A ^
652+ ((QuotientImageFinset Q₁).card *
653+ (QuotientImageFinset Q₂).card * (QuotientImageFinset Q₂).card) := by
654+ rw [card_comparisonImageQuotientRules Q₁ Q₂,
655+ comparisonMap_image_card_eq_product_images_card Q₁ Q₂]
656+
657+ /--
658+ Comparison-image quotient rules are bounded by assigning labels to every
659+ left/right/right component-image triple.
660+ -/
661+ theorem card_comparisonImageQuotientRules_le_product_images
662+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
663+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
664+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
665+ Fintype.card (QuotientImageBucket (comparisonMap Q₁ Q₂) → A) ≤
666+ Fintype.card A ^
667+ ((QuotientImageFinset Q₁).card *
668+ (QuotientImageFinset Q₂).card * (QuotientImageFinset Q₂).card) := by
669+ rw [card_comparisonImageQuotientRules_eq_product_images Q₁ Q₂]
670+
399671end OrdvecFormalization
0 commit comments