Workspace IndexMath › Day 8

Relations and Equivalence Classes TODO

Math · Day 8 / 52 · July — Discrete Math & Logic (Day 3-10)

Concept

A binary relation on a set is defined as a subset of the Cartesian product — it enumerates which pairs of elements are related. A relation that satisfies reflexivity, symmetry, and transitivity all at once is an equivalence relation. An equivalence relation splits a set into disjoint equivalence classes, and conversely any partition defines an equivalence relation, so the two correspond one-to-one. The set of all equivalence classes is called the quotient set, and an operation defined on the quotient set is well-defined only if the result doesn't depend on which representative element you pick. Congruence modulo n on the integers is the canonical equivalence relation, and its equivalence classes are the residue classes.

Deciding what counts as "the same" is the essence of deduplication, cache keys, and replay protection, and if the criterion you pick breaks symmetry or transitivity, that's a bug waiting to happen.

Code & Formula

# 관계와 동치류 — 정수의 "mod n 합동"이 동치관계임을 반사·대칭·추이성으로 검증하고,
# 그 동치류(잉여류)들이 원래 집합을 서로소인 조각들로 정확히 파티션함을 확인.

MOD = 5
universe = list(range(-6, 12))   # 동치관계 검증에 쓸 표본 집합

def related(a, b):
    return (a - b) % MOD == 0

def is_reflexive(xs):
    return all(related(x, x) for x in xs)

def is_symmetric(xs):
    return all(related(a, b) == related(b, a) for a in xs for b in xs)

def is_transitive(xs):
    return all(
        not (related(a, b) and related(b, c)) or related(a, c)
        for a in xs for b in xs for c in xs
    )

print(f"mod {MOD} 합동 관계 검증 (표본 {len(universe)}개):")
print("  반사성 :", is_reflexive(universe))
print("  대칭성 :", is_symmetric(universe))
print("  추이성 :", is_transitive(universe))

# 동치류(잉여류) 계산: 같은 나머지를 갖는 원소끼리 묶는다.
classes = {r: [] for r in range(MOD)}
for x in universe:
    classes[x % MOD].append(x)

print(f"\n{MOD}개의 동치류(잉여류)로 파티션:")
for r, members in classes.items():
    print(f"  [{r}] = {members}")

# 파티션 검증: 동치류들이 서로소이고, 합쳐서 universe 전체가 되는지.
all_members = [x for members in classes.values() for x in members]
pairwise_disjoint = len(all_members) == len(set(all_members))
covers_universe = set(all_members) == set(universe)
print("\n서로소(중복 없음)?", pairwise_disjoint, " / 전체를 덮음?", covers_universe)

Exercise

Pick a criterion for treating two orders or transactions as "the same," verify reflexivity, symmetry, and transitivity for it, and construct a counterexample where transitivity breaks.

Practical Connection

Transaction-hash- or nonce-based duplicate detection, and merging equivalent states in a state machine, are all instances of equivalence classes — and in Verex, the identifiers used to point at "the same market" or "the same outcome" are themselves a definition of what counts as equal.

If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/math-50-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.


한국어

관계와 동치류 TODO

Math · Day 8 / 52 · 7월 — 이산수학·논리 (Day 3–10)

파티션으로 상태 그룹핑

개념

집합 위의 이항 관계는 곱집합의 부분집합으로 정의되며, 어떤 두 원소가 관계를 맺는지를 나열한 것이다. 반사성, 대칭성, 추이성을 모두 만족하는 관계를 동치관계라 한다. 동치관계는 집합을 서로소인 동치류들로 쪼개고, 반대로 임의의 파티션은 하나의 동치관계를 정의하므로 둘은 일대일로 대응한다. 동치류 전체의 집합을 몫집합이라 하며, 몫집합 위의 연산은 대표원을 무엇으로 고르든 결과가 같아야 잘 정의된다. 정수의 모듈로 n 합동이 대표적 동치관계이고 그 동치류가 잉여류다.

무엇을 같은 것으로 볼지 정하는 일은 중복 제거, 캐시 키, 리플레이 방지 같은 설계의 본질이며, 기준이 대칭성이나 추이성을 깨면 그대로 버그가 된다.

코드 · 수식

# 관계와 동치류 — 정수의 "mod n 합동"이 동치관계임을 반사·대칭·추이성으로 검증하고,
# 그 동치류(잉여류)들이 원래 집합을 서로소인 조각들로 정확히 파티션함을 확인.

MOD = 5
universe = list(range(-6, 12))   # 동치관계 검증에 쓸 표본 집합

def related(a, b):
    return (a - b) % MOD == 0

def is_reflexive(xs):
    return all(related(x, x) for x in xs)

def is_symmetric(xs):
    return all(related(a, b) == related(b, a) for a in xs for b in xs)

def is_transitive(xs):
    return all(
        not (related(a, b) and related(b, c)) or related(a, c)
        for a in xs for b in xs for c in xs
    )

print(f"mod {MOD} 합동 관계 검증 (표본 {len(universe)}개):")
print("  반사성 :", is_reflexive(universe))
print("  대칭성 :", is_symmetric(universe))
print("  추이성 :", is_transitive(universe))

# 동치류(잉여류) 계산: 같은 나머지를 갖는 원소끼리 묶는다.
classes = {r: [] for r in range(MOD)}
for x in universe:
    classes[x % MOD].append(x)

print(f"\n{MOD}개의 동치류(잉여류)로 파티션:")
for r, members in classes.items():
    print(f"  [{r}] = {members}")

# 파티션 검증: 동치류들이 서로소이고, 합쳐서 universe 전체가 되는지.
all_members = [x for members in classes.values() for x in members]
pairwise_disjoint = len(all_members) == len(set(all_members))
covers_universe = set(all_members) == set(universe)
print("\n서로소(중복 없음)?", pairwise_disjoint, " / 전체를 덮음?", covers_universe)

연습

주문이나 트랜잭션을 같은 것으로 볼 기준을 하나 정해 반사·대칭·추이성을 각각 검증하고, 추이성이 깨지는 기준의 반례를 만들어보라.

실무 · Verex 연결

트랜잭션 해시나 nonce 기반 중복 판정, 상태 머신의 동치 상태 병합이 모두 동치류 개념이고, Verex에서 같은 시장·같은 결과를 가리키는 식별자 계산 역시 무엇을 같은 것으로 볼지에 대한 정의다.

공부한 날 원본 커리큘럼(docs/knowledge/math-50-curriculum.md)의 이 줄에 노트 링크와 ✅ 를 붙이면, 이 자리는 노트 본문으로 바로 이어집니다. 노트 없이 이 페이지에 바로 적어도 됩니다 — 다만 다시 생성하면 덮어쓰이므로, 남길 글은 docs/algorithms/ 의 마크다운으로 쓰는 편이 안전합니다.

← 7. Big-O & 가스9. 카운팅 원리(순열·조합·이항계수) →