Nick은 최근 아틴 집합(artinian set), 줄여서 아틴(artinal)이라 부르는 특별한 종류의 집합을 배웠습니다. 이 집합의 장점은 저마다 유한한 표현을 가진다는 점이어서 컴퓨터로 처리할 수 있습니다. 형식적인 정의는 다소 복잡합니다.
- 높이가 ≤0인 아틴은 오직 공집합 ∅ 하나뿐입니다.
- 양의 정수 N에 대해, 높이가 ≤N인 아틴은 그 원소가 모두 높이 ≤N−1인 아틴인 유한 집합들과 정확히 일치합니다.
- 어떤 양의 정수 N에 대해 A가 높이 ≤N인 아틴이면, A를 아틴이라고 합니다.
- 모든 아틴의 모임을 U로 씁니다.
높이가 ≤N인 아틴은 높이가 ≤N+1인 아틴이기도 하므로, 임의의 아틴 A에 대해 높이 h(A)를 A가 높이 ≤N인 아틴이 되게 하는 가장 작은 N으로 정의합니다. 높이가 N인 아틴을 N-아틴이라고 부릅니다.
여기에 두 가지 개념이 더 필요합니다. U 위의 표준 순서(canonical order, <로 표기)와 아틴의 표준형(canonical form)입니다.
- 높이가 ≤N인 아틴 A의 표준형은, 각 Ai가 높이 ≤N−1인 아틴이고 A1<A2<⋯<As를 만족하도록 원소를 나열한 A={A1,A2,…,As}입니다.
- 표준형으로 쓴 두 아틴 A={A1,…,As}와 B={B1,…,Bt}가 모두 높이 ≤N일 때, A<B인 것은 다음을 만족하는 정수 k (1≤k≤min(s+1,t))가 존재하는 것과 동치입니다: 모든 1≤j<k에 대해 Aj=Bj이고, k=s+1이거나 Ak<Bk이다. 직관적으로는, 정렬된 원소 목록을 왼쪽부터 비교하여 처음으로 다른 원소가 순서를 결정하고, 한쪽이 다른 쪽의 진부분 목록이면 그쪽이 앞섭니다.
아틴의 표준 표현(canonical representation)은 문자 {, }, ,로 이루어진 문자열입니다. repr(∅) = {}이고, A={A1,…,As}가 표준형이면 repr(A) = { + repr(A1) + , + ⋯ + , + repr(As) + }입니다.
표준 표현은 길어지기 쉬우므로 다음 약칭을 도입합니다. 각 정수 N≥0에 대해 유한 서수(finite ordinal) N을 귀납적으로 정의합니다: 0:=∅이고 N+1:={N}∪N이며, 따라서 N={0,1,…,N−1}입니다. 축약 표준 표현(reduced canonical representation)은 표준 표현에서, 자신보다 큰 서수 M (M>N)의 출현 안에 포함되지 않은 모든 서수 N의 출현을 십진수 N으로 바꾼 것입니다.
아틴에 대한 연산은 다음과 같으며, 우선순위가 높은 것부터 낮은 것 순으로 나열합니다.
- 단항 교집합 ∩: 공집합이 아닌 아틴 A={A1,…,As}에 대해 ∩A:=A1∩A2∩⋯∩As.
- 단항 합집합 ∪: 임의의 아틴 A={A1,…,As}에 대해 ∪A:=A1∪A2∪⋯∪As이고, ∪∅ := ∅.
- 이항 교집합 ∩: A∩B:={x:x∈A 이고 x∈B}.
- 이항 합집합 ∪: A∪B:={x:x∈A 또는 x∈B}.
- 이항 차집합 −: A−B:={x∈A:x∈/B}.
- 이항 대칭차 △: A△B:=(A−B)∪(B−A).
아틴 사이의 관계는 다음과 같이 정의합니다.
- 상등 =과 부등 ≠.
- 포함 ⊂과 ⊃: A⊂B⇔B⊃A⇔(x∈A⇒x∈B). 즉 ⊂은 "부분집합 또는 상등"을 뜻합니다.
- 원소 관계 ∈과 ∋: B∈A (동치로 A∋B)는 B가 A의 원소임을 뜻합니다.
- 위에서 설명한 표준 순서 관계 <, ≤, ≥, >. 여기서 A≤B⇔(A<B 또는 A=B), A>B⇔B<A, A≥B⇔B≤A입니다.
여러분은 아틴으로 계산을 수행하는 작은 프로그램을 실행해야 합니다. 프로그램은 한 줄에 하나씩 놓인 연산자들의 나열입니다. 연산자는 다섯 종류입니다.
- 대입 ⟨ident⟩
:=⟨expr⟩ — 변수 ⟨ident⟩를 ⟨expr⟩의 값으로 설정합니다.
- 평가
!⟨expr⟩ — ⟨expr⟩를 평가하여 그 축약 표준 표현을 한 줄에 출력합니다.
- 검사
?⟨expr⟩⟨relation⟩⟨expr⟩ — 조건을 평가하여 TRUE 또는 FALSE를 한 줄에 출력합니다.
- 주석
#⟨임의의 문자열⟩ — 그 줄 전체를 출력으로 복사합니다.
- 빈 연산자 — 공백 문자만으로 이루어진 줄로, 아무 일도 하지 않습니다.
문법에는 다음 정의를 사용합니다.
- ⟨ident⟩ ::= ⟨alpha⟩{⟨alpha⟩}
- ⟨alpha⟩ ::= ⟨letter⟩ | ⟨digit⟩ |
_
- ⟨digit⟩ ::=
0 | 1 | … | 9
- ⟨letter⟩ ::=
A | … | Z | a | … | z
- ⟨expr⟩ ::=
{ [ ⟨expr⟩ { ,⟨expr⟩ } ] } | ⟨ident⟩ | ⟨expr⟩⟨binop⟩⟨expr⟩ | ⟨unop⟩⟨expr⟩ | (⟨expr⟩)
- ⟨binop⟩ ::=
+ | * | - | ^
- ⟨unop⟩ ::=
+ | *
- ⟨relation⟩ ::=
< | > | = | <= | >= | <> | -> | <- | << | >>
이항 연산자 +, *, -, ^는 각각 ∪, ∩, −, △을 나타내고, 단항 연산자 +, *는 각각 ∪, ∩을 나타냅니다. 관계 <, >, =, <=, >=, <>, ->, <-, <<, >>는 각각 <, >, =, ≤, ≥, ≠, ∈, ∋, ⊂, ⊃을 나타냅니다. 괄호 (와 )는 통상적으로 우선순위를 바꿉니다. 하나의 ⟨ident⟩를 이루는 ⟨alpha⟩ 문자들만 예외로 하고, 임의의 두 토큰은 임의 개수의 공백 문자(스페이스와 탭)로 구분할 수 있습니다.
프로그램 실행 전에, 이름이 음이 아닌 정수 N의 (앞자리 0 없는) 십진 표기인 모든 변수는 유한 서수 N으로 미리 설정됩니다. 그 밖의 모든 변수는 ∅으로 시작합니다. 식별자는 대소문자를 구별합니다.