@@ -252,6 +252,106 @@ theorem card_productQuotientRules {Z₁ Z₂ A : Type}
252252 Fintype.card A ^ (Fintype.card Z₁ * Fintype.card Z₂) := by
253253 rw [Fintype.card_fun, Fintype.card_prod]
254254
255+ /--
256+ The reachable image of a product map is contained in the product of the two
257+ reachable component images.
258+ -/
259+ theorem productMap_image_subset_product_images
260+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
261+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
262+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
263+ QuotientImageFinset (productMap Q₁ Q₂) ⊆
264+ (QuotientImageFinset Q₁).product (QuotientImageFinset Q₂) := by
265+ intro z hz
266+ rcases Finset.mem_image.mp hz with ⟨p, _hp, hp⟩
267+ rw [← hp]
268+ exact Finset.mem_product.mpr
269+ ⟨Finset.mem_image.mpr ⟨p.1 , Finset.mem_univ p.1 , rfl⟩,
270+ Finset.mem_image.mpr ⟨p.2 , Finset.mem_univ p.2 , rfl⟩⟩
271+
272+ /--
273+ The reachable image of a product map is exactly the product of the reachable
274+ component images.
275+ -/
276+ theorem productMap_image_eq_product_images
277+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
278+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
279+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
280+ QuotientImageFinset (productMap Q₁ Q₂) =
281+ (QuotientImageFinset Q₁).product (QuotientImageFinset Q₂) := by
282+ apply Finset.Subset.antisymm
283+ · exact productMap_image_subset_product_images Q₁ Q₂
284+ · intro z hz
285+ rcases Finset.mem_product.mp hz with ⟨hz₁, hz₂⟩
286+ rcases Finset.mem_image.mp hz₁ with ⟨x, _hx, hx⟩
287+ rcases Finset.mem_image.mp hz₂ with ⟨y, _hy, hy⟩
288+ exact Finset.mem_image.mpr
289+ ⟨(x, y), Finset.mem_univ (x, y), Prod.ext hx hy⟩
290+
291+ /--
292+ The number of reachable product codes is exactly the product of the numbers of
293+ reachable component codes.
294+ -/
295+ theorem productMap_image_card_eq_product_images_card
296+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
297+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
298+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
299+ (QuotientImageFinset (productMap Q₁ Q₂)).card =
300+ (QuotientImageFinset Q₁).card * (QuotientImageFinset Q₂).card := by
301+ rw [productMap_image_eq_product_images Q₁ Q₂]
302+ simp
303+
304+ /--
305+ The number of reachable product codes is bounded by the product of the numbers
306+ of reachable component codes.
307+ -/
308+ theorem productMap_image_card_le_product_images_card
309+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
310+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
311+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
312+ (QuotientImageFinset (productMap Q₁ Q₂)).card ≤
313+ (QuotientImageFinset Q₁).card * (QuotientImageFinset Q₂).card := by
314+ rw [productMap_image_card_eq_product_images_card Q₁ Q₂]
315+
316+ /--
317+ Rules on the reachable product image have search-space size
318+ `|A| ^ |image(productMap Q₁ Q₂)|`.
319+ -/
320+ theorem card_productImageQuotientRules
321+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
322+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
323+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
324+ Fintype.card (QuotientImageBucket (productMap Q₁ Q₂) → A) =
325+ Fintype.card A ^ (QuotientImageFinset (productMap Q₁ Q₂)).card := by
326+ exact card_quotientImageRules (productMap Q₁ Q₂)
327+
328+ /--
329+ Rules on the reachable product image have search-space size
330+ `|A| ^ (|image Q₁| * |image Q₂|)`.
331+ -/
332+ theorem card_productImageQuotientRules_eq_product_images
333+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
334+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
335+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
336+ Fintype.card (QuotientImageBucket (productMap Q₁ Q₂) → A) =
337+ Fintype.card A ^
338+ ((QuotientImageFinset Q₁).card * (QuotientImageFinset Q₂).card) := by
339+ rw [card_productImageQuotientRules Q₁ Q₂,
340+ productMap_image_card_eq_product_images_card Q₁ Q₂]
341+
342+ /--
343+ Product-image quotient rules are bounded by assigning labels to every
344+ component-image pair.
345+ -/
346+ theorem card_productImageQuotientRules_le_product_images
347+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
348+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
349+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
350+ Fintype.card (QuotientImageBucket (productMap Q₁ Q₂) → A) ≤
351+ Fintype.card A ^
352+ ((QuotientImageFinset Q₁).card * (QuotientImageFinset Q₂).card) := by
353+ rw [card_productImageQuotientRules_eq_product_images Q₁ Q₂]
354+
255355namespace RuleFactorsThrough
256356
257357/-- Pairing two product-factorized targets is equivalent to factoring both components. -/
@@ -299,6 +399,26 @@ structure ComparisonObs (Ω₁ Ω₂ : Type) where
299399 second : Ω₂
300400deriving DecidableEq
301401
402+ /-- Finite comparison observations are equivalent to left/right/right triples. -/
403+ def comparisonObsEquivProd (Ω₁ Ω₂ : Type ) :
404+ ComparisonObs Ω₁ Ω₂ ≃ Ω₁ × Ω₂ × Ω₂ where
405+ toFun c := (c.left, c.first, c.second)
406+ invFun x := {
407+ left := x.1
408+ first := x.2 .1
409+ second := x.2 .2
410+ }
411+ left_inv c := by
412+ cases c
413+ rfl
414+ right_inv x := by
415+ cases x
416+ rfl
417+
418+ instance comparisonObsFintype {Ω₁ Ω₂ : Type }
419+ [Fintype Ω₁] [Fintype Ω₂] : Fintype (ComparisonObs Ω₁ Ω₂) :=
420+ Fintype.ofEquiv (Ω₁ × Ω₂ × Ω₂) (comparisonObsEquivProd Ω₁ Ω₂).symm
421+
302422/-- Product quotient for a left item and two right items. -/
303423def comparisonMap {Ω₁ Ω₂ Z₁ Z₂ : Type }
304424 (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
@@ -387,4 +507,142 @@ theorem rankByScore_factorsThrough_of_score_factorsThrough
387507 cases c
388508 simp [rankByScore, comparisonMap, hscoreQ]
389509
510+ /-! ## Comparison image bounds -/
511+
512+ /--
513+ The ambient box of reachable comparison codes induced by one left image and two
514+ right images.
515+ -/
516+ def ComparisonImageBox {Ω₁ Ω₂ Z₁ Z₂ : Type }
517+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
518+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) : Finset (ComparisonObs Z₁ Z₂) :=
519+ ((QuotientImageFinset Q₁).product
520+ ((QuotientImageFinset Q₂).product (QuotientImageFinset Q₂))).image
521+ (fun z => {
522+ left := z.1
523+ first := z.2 .1
524+ second := z.2 .2
525+ })
526+
527+ /--
528+ The reachable image of a comparison map is contained in the box of reachable
529+ left/right/right component codes.
530+ -/
531+ theorem comparisonMap_image_subset_imageBox
532+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
533+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
534+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
535+ QuotientImageFinset (comparisonMap Q₁ Q₂) ⊆
536+ ComparisonImageBox Q₁ Q₂ := by
537+ intro z hz
538+ rcases Finset.mem_image.mp hz with ⟨c, _hc, hc⟩
539+ rw [← hc]
540+ unfold ComparisonImageBox
541+ apply Finset.mem_image.mpr
542+ refine ⟨(Q₁ c.left, (Q₂ c.first, Q₂ c.second)), ?_, rfl⟩
543+ exact Finset.mem_product.mpr
544+ ⟨Finset.mem_image.mpr ⟨c.left, Finset.mem_univ c.left, rfl⟩,
545+ Finset.mem_product.mpr
546+ ⟨Finset.mem_image.mpr ⟨c.first, Finset.mem_univ c.first, rfl⟩,
547+ Finset.mem_image.mpr ⟨c.second, Finset.mem_univ c.second, rfl⟩⟩⟩
548+
549+ /--
550+ The reachable image of a comparison map is exactly the box of reachable
551+ left/right/right component codes.
552+ -/
553+ theorem comparisonMap_image_eq_imageBox
554+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
555+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
556+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
557+ QuotientImageFinset (comparisonMap Q₁ Q₂) =
558+ ComparisonImageBox Q₁ Q₂ := by
559+ apply Finset.Subset.antisymm
560+ · exact comparisonMap_image_subset_imageBox Q₁ Q₂
561+ · intro z hz
562+ unfold ComparisonImageBox at hz
563+ rcases Finset.mem_image.mp hz with ⟨p, hp, hpz⟩
564+ rcases Finset.mem_product.mp hp with ⟨hzleft, hzrights⟩
565+ rcases Finset.mem_product.mp hzrights with ⟨hzfirst, hzsecond⟩
566+ rcases Finset.mem_image.mp hzleft with ⟨x, _hxmem, hx⟩
567+ rcases Finset.mem_image.mp hzfirst with ⟨y₁, _hy₁mem, hy₁⟩
568+ rcases Finset.mem_image.mp hzsecond with ⟨y₂, _hy₂mem, hy₂⟩
569+ apply Finset.mem_image.mpr
570+ refine ⟨{ left := x, first := y₁, second := y₂ }, Finset.mem_univ _, ?_⟩
571+ rw [← hpz]
572+ simp [comparisonMap, hx, hy₁, hy₂]
573+
574+ /--
575+ The number of reachable comparison codes is exactly
576+ `|image Q₁| * |image Q₂| * |image Q₂|`.
577+ -/
578+ theorem comparisonMap_image_card_eq_product_images_card
579+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
580+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
581+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
582+ (QuotientImageFinset (comparisonMap Q₁ Q₂)).card =
583+ (QuotientImageFinset Q₁).card *
584+ (QuotientImageFinset Q₂).card * (QuotientImageFinset Q₂).card := by
585+ rw [comparisonMap_image_eq_imageBox Q₁ Q₂]
586+ unfold ComparisonImageBox
587+ rw [Finset.card_image_of_injective]
588+ · simp [mul_assoc]
589+ · intro p₁ p₂ h
590+ exact Prod.ext (congrArg ComparisonObs.left h)
591+ (Prod.ext (congrArg ComparisonObs.first h)
592+ (congrArg ComparisonObs.second h))
593+
594+ /--
595+ The number of reachable comparison codes is bounded by
596+ `|image Q₁| * |image Q₂| * |image Q₂|`.
597+ -/
598+ theorem comparisonMap_image_card_le_product_images_card
599+ {Ω₁ Ω₂ Z₁ Z₂ : Type }
600+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂]
601+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
602+ (QuotientImageFinset (comparisonMap Q₁ Q₂)).card ≤
603+ (QuotientImageFinset Q₁).card *
604+ (QuotientImageFinset Q₂).card * (QuotientImageFinset Q₂).card := by
605+ rw [comparisonMap_image_card_eq_product_images_card Q₁ Q₂]
606+
607+ /--
608+ Rules on the reachable comparison image have search-space size
609+ `|A| ^ |image(comparisonMap Q₁ Q₂)|`.
610+ -/
611+ theorem card_comparisonImageQuotientRules
612+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
613+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
614+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
615+ Fintype.card (QuotientImageBucket (comparisonMap Q₁ Q₂) → A) =
616+ Fintype.card A ^ (QuotientImageFinset (comparisonMap Q₁ Q₂)).card := by
617+ exact card_quotientImageRules (comparisonMap Q₁ Q₂)
618+
619+ /--
620+ Rules on the reachable comparison image have search-space size
621+ `|A| ^ (|image Q₁| * |image Q₂| * |image Q₂|)`.
622+ -/
623+ theorem card_comparisonImageQuotientRules_eq_product_images
624+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
625+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
626+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
627+ Fintype.card (QuotientImageBucket (comparisonMap Q₁ Q₂) → A) =
628+ Fintype.card A ^
629+ ((QuotientImageFinset Q₁).card *
630+ (QuotientImageFinset Q₂).card * (QuotientImageFinset Q₂).card) := by
631+ rw [card_comparisonImageQuotientRules Q₁ Q₂,
632+ comparisonMap_image_card_eq_product_images_card Q₁ Q₂]
633+
634+ /--
635+ Comparison-image quotient rules are bounded by assigning labels to every
636+ left/right/right component-image triple.
637+ -/
638+ theorem card_comparisonImageQuotientRules_le_product_images
639+ {Ω₁ Ω₂ Z₁ Z₂ A : Type }
640+ [Fintype Ω₁] [Fintype Ω₂] [DecidableEq Z₁] [DecidableEq Z₂] [Fintype A]
641+ (Q₁ : Ω₁ → Z₁) (Q₂ : Ω₂ → Z₂) :
642+ Fintype.card (QuotientImageBucket (comparisonMap Q₁ Q₂) → A) ≤
643+ Fintype.card A ^
644+ ((QuotientImageFinset Q₁).card *
645+ (QuotientImageFinset Q₂).card * (QuotientImageFinset Q₂).card) := by
646+ rw [card_comparisonImageQuotientRules_eq_product_images Q₁ Q₂]
647+
390648end OrdvecFormalization
0 commit comments