값 정규화날짜 정규화구간앨런 구간 관계이행성반순서사실탐색기의결결과만 나이Y2KEDTFLLM 판정결정론한국어 자연어처리
‘가결’과 ‘원안대로 가결’은 같은 값인가 — 글자 유사도를 걷어 내고 값의 ‘해상도’로 비교하기
코어닷투데이 사실탐색기는 부산시의회 회의록의 '원안 가결'과 '원안대로 가결'을 서로 다른 값으로 보고, 한 안건에 의결결과를 둘씩 열어 두고 있었습니다. 그런 안건이 134개였습니다. 같은 엔진은 '2024년 4월 1일부터'와 '…까지'를 같은 값으로 보았습니다. 원인은 둘 다 값을 글자 조각의 겹침으로 비교한 데 있었습니다. 날짜·나이 범위·의결결과를 칸이 있는 구조로 읽고, 칸이 빈 값은 '덜 자세한 같은 값'으로 다루는 계층을 넣었습니다. 그 결과 판정이 바뀐 값 쌍은 열 개였지만 명제가 136개 줄었고, 설명 안 되는 대체가 7건에서 5건으로 줄었습니다. Y2K와 엑셀의 1900년 윤년, 앨런의 구간 관계 13가지, 푸앵카레와 루스의 '같은데 다른' 역설을 따라가며, 값의 해상도가 왜 값의 일부인지, 2026년의 판정 모델은 어디에 서야 하는지 정리했습니다.
코어닷투데이2026-10-2744분
?
질문
'원안 가결'과 '원안대로 가결'은 같은 값입니다. '2024년 4월 1일부터'와 '2024년 4월 1일까지'는 다른 값입니다. 그런데 글자 조각이 겹치는 비율로 재면 앞의 쌍은 0.33으로 '다르다', 뒤의 쌍은 '같다'가 됩니다. 값을 글자로 비교하면 왜 이렇게 거꾸로 될까요?
→
이번에 한 일
사실탐색기의 값 비교(C3) 앞에 날짜·나이 범위·의결결과를 칸으로 읽는 계층을 넣었습니다. 빈 칸이 있는 값은 '덜 자세한 같은 값'으로 따로 다룹니다. 부산 기록 362건과 DART 2,851건으로 전체 파이프라인을 다시 돌려 전후를 쟀고, 같은 값 쌍을 로컬 판정 모델에도 물었습니다.
!
결과
판정이 바뀐 값 쌍은 열 개이고, 손으로 보니 모두 맞았습니다. 그 열 쌍이 회의록 곳곳에 되풀이돼 부산 명제가 136개 줄었고, 설명 안 되는 대체는 7건에서 5건으로 줄었습니다. 질문 회귀는 25/25, 16/16을 지켰습니다. 9B 판정 모델은 73쌍 중 71쌍을 맞혔지만, 틀린 두 쌍에는 확신도 0.9 이상으로 지어낸 이유를 댔습니다.
사실탐색기는 공적 기록에서 "지금 참인 것"을 유지하는 엔진입니다. 기록마다 (무엇이, 어떤 속성이, 어떤 값인가)를 뽑아 명제로 만들고, 같은 속성에 다른 값이 들어오면 더 권위 있는 쪽이 옛 값을 닫습니다. 같은 값이 들어오면 근거를 하나 더 붙입니다. 그래서 엔진의 가장 위험한 판단은 두 값이 같은가입니다. 설계 문서에서는 이 판단을 C3라고 부릅니다.
지난 특집 「‘비슷하다’는 네 가지 질문이다」에서 이 C3가 글자 유사도에 기대고 있다는 문제를 다뤘습니다. 두 값의 음절 조각(bigram)이 60% 이상 겹치면 같은 값으로 봤는데, 조례 부칙의 '1981년 1월 1일부터 시행'과 '1984년 1월 1일부터 시행'이 71% 겹쳐 같은 값이 됐습니다. 그날 수 검사로 그 버그를 고쳤고, 글 끝에 숙제를 하나 남겼습니다. '만 19세부터 34세까지'와 '만 19세~34세'처럼 같은 값인데 글자가 안 겹치는 쌍은 여전히 충돌로 판정된다는 것입니다. 해법으로 값을 구간으로 풀자고 제안했습니다.
이번 글은 그 숙제를 실제로 엔진에 넣고 잰 기록입니다. 그런데 넣기 전에 코퍼스의 값 쌍을 다시 훑다가 더 큰 것을 발견했습니다. 부산시의회 회의록은 같은 안건의 결과를 '원안 가결'로도, '원안대로 가결'로도 적습니다. 두 표기의 조각 겹침은 0.33입니다. 엔진은 이 둘을 다른 값으로 보았습니다. 회의록은 1인칭 기록이라 다른 값끼리 서로를 닫을 권위가 없으니, 두 값이 나란히 열려 있었습니다. 시민이 "이 조례안 어떻게 됐어?"라고 물으면 엔진은 두 개의 답을 들고 있었던 셈입니다. 그런 안건이 134개였습니다.
거꾸로 된 경우도 있었습니다. 회귀 사례를 먼저 적고 실패를 확인하는 단계에서, '2024년 4월 1일부터'와 '2024년 4월 1일까지'를 엔진이 같은 값으로 보고 있다는 것이 드러났습니다. 시작일과 마감일이 같은 값이 되는 것입니다.
두 문제의 뿌리는 같습니다. 값을 글자로 비교했다는 것입니다. 이 글은 그 뿌리를 뽑은 과정입니다. 날짜·나이 범위·의결결과를 칸이 있는 구조로 읽고, 칸이 빈 값을 따로 다루는 방법을 설명합니다. 그 과정에서 마주친 오래된 문제들, 즉 Y2K, 앨런의 구간 관계, '같은데 다른' 역설도 함께 따라갑니다.
1. 값은 언제부터 글자였나
컴퓨터 안의 값이 글자처럼 다뤄져 사고가 난 역사는 길고, 그 사고들은 대개 해상도를 아끼거나 잃은 데서 시작했습니다.
연도 두 자리: 해상도를 아낀 대가 (1960~1999)
1960~70년대 프로그래머들은 연도를 두 자리로 적었습니다. 저장 공간이 비쌌고, '99'가 1999년이라는 것은 누구나 알았습니다. 문제는 그 '누구나'가 사람이었다는 데 있습니다. '00'이 1900년인지 2000년인지는 기록이 말하지 않습니다. 세기라는 칸이 빈 값입니다. 사람은 문맥으로 채우지만, 프로그램은 빈 칸을 아무렇게나 채웠습니다.
미국 상원 Y2K 특별위원회의 2000년 최종 보고서에 따르면, 미국 상무부는 미국 정부와 기업이 이 문제에 약 1,000억 달러를 썼다고 추산했습니다. 그렇게 고치고도 사고는 남았습니다. 같은 보고서의 부록은 미 국방부 위성 정보 체계의 지상국 장애와 함께, 고려대학교 졸업증명서가 1900년 날짜로 발급된 일을 적어 두었습니다. 빈 칸을 잘못 채운 값은 겉보기에 멀쩡한 날짜였습니다.
1900년 2월 29일: 호환성을 위해 남긴 틀린 값
엑셀에는 존재하지 않는 날짜가 있습니다. 1900년 2월 29일입니다. 1900년은 윤년이 아닌데, 엑셀은 윤년으로 셉니다. 마이크로소프트의 공식 문서는 이유를 이렇게 적습니다. 로투스 1-2-3이 1900년을 윤년으로 잘못 가정했고, 엑셀은 같은 일련번호 날짜 체계를 써서 로투스와 호환되려고 그 가정을 그대로 따랐다는 것입니다. 그 대가로 1900년 3월 1일 이전 날짜의 요일 함수는 틀린 값을 냅니다.
이 사례가 말해 주는 것은, 날짜를 표기가 아니라 값(일련번호)으로 바꾸는 순간 비교는 쉬워지지만, 그 변환 규칙이 곧 진실이 된다는 점입니다. 변환 규칙이 틀리면 모든 비교가 함께 틀립니다. 그래서 사실탐색기의 값 타입 규칙은 하나하나 회귀 사례로 고정합니다.
표기를 하나로: ISO 8601 (1988)
국제표준화기구는 1988년 ISO 8601 첫 판에서 날짜를 '연-월-일' 순서로 적는 방법을 정했습니다. '2026-03-26'입니다. 큰 단위에서 작은 단위로 가므로 글자 순서대로 정렬하면 시간 순서가 되고, 나라마다 다른 '03/26'과 '26/03'의 혼동도 없앱니다. DART 공시는 이 표기를 씁니다.
하지만 표준이 정한 것은 쓰는 법이지 세상이 쓰는 법이 아닙니다. 기사는 여전히 '3월26일'이라고 쓰고, 공고는 '2026. 9. 21.(월)'이라고 씁니다. 같은 날을 다르게 적은 값을 같은 값으로 맞추는 일은 지난 수정에서 했습니다. 남은 문제는 덜 적은 값입니다.
모르는 칸을 적는 법: X (2000년대~2019)
'3월 26일'에서 연도를 모른다는 사실을 어떻게 적을까요? 시간 표현에 주석을 다는 언어학 표준 TimeML의 TIMEX3는 모르는 자리를 X로 채웁니다. '5월 20일'의 값은 'XXXX-05-20'입니다. 미국 의회도서관이 만든 확장 날짜·시간 형식(EDTF)도 같은 생각을 따릅니다. 이 형식은 2019년 ISO 8601-2에 들어갔습니다. 1단계에서는 오른쪽 자리만 비울 수 있고('1985-04-XX', '2004-XX'), 2단계에서는 아무 자리나 비울 수 있습니다. 'XXXX-12-XX'는 "어느 해 12월의 어느 날"입니다.
위키데이터는 다른 방식을 씁니다. 날짜마다 정밀도 숫자를 붙입니다. 9는 연, 10은 월, 11은 일입니다. '2026년 3월'은 정밀도 10인 날짜입니다.
두 방식 모두 같은 원칙을 말합니다. 해상도는 값의 일부입니다. '3월 26일'은 '2026-03-26'을 잘못 적은 값이 아니라, 연도를 말하지 않은 다른 값입니다. 두 값은 같지 않지만 서로 어긋나지도 않습니다. 사실탐색기에는 이 관계를 적을 칸이 없었습니다. 같거나 다르거나, 둘 중 하나였습니다.
2. 답은 셋이 아니라 넷이다
지난 글에서는 값 비교에 '같음·포함·겹침·분리·판단 보류' 다섯 칸을 제안했습니다. 실제 엔진에 넣으려고 코퍼스의 값 쌍 3,317개를 하나하나 보니, AGS가 알아야 하는 것은 그보다 단순했습니다. 새 값이 옛 값을 닫아야 하는가입니다. 이 물음에 답하는 데 필요한 칸은 넷이었습니다.
네 번째 칸이 중요합니다. 이 계층은 자신 있을 때만 답합니다. '2025년 10월 6일 ~ 2025년 11월 14일'과 '10월 31일 마감'은 하나는 기간이고 하나는 날짜라서 판단하지 않습니다. 그러면 다음 단계인 수 검사가 두 값의 수 묶음이 다르다는 것을 보고 충돌로 판정합니다. 기간의 끝(11월 14일)과 마감일(10월 31일)을 비교하면 풀릴 것처럼 보이지만, '마감'이 그 기간의 끝을 말하는지 다른 일정의 끝을 말하는지는 글자만으로 알 수 없습니다. 그래서 짐작하지 않습니다. 사실탐색기의 원칙 2번, '추측 금지'입니다.
'값 말고 다른 말이 남으면 판단하지 않는다'는 규칙도 같은 이유입니다. '부산광역시에 주민등록을 둔 만 19세부터 34세까지의 무주택 청년'과 '…만 19세~34세 무주택 청년'은 나이 구간은 같지만, 나이를 떼고 남은 말이 '의' 한 글자만큼 다릅니다. 사람 눈에는 같은 말이지만, 코드는 남은 말이 정확히 같을 때만 '같은 값'이라고 말합니다. 이 쌍은 다음 단계로 넘어가고, 긴 공통 문맥 덕분에 글자 점수 0.68로 같은 값이 됩니다. 결과는 같지만 판정한 층이 다릅니다.
아래 실험실에서 직접 넣어 보세요. 왼쪽은 글자 점수, 오른쪽은 값으로 읽은 결과입니다. 판정 함수는 엔진의 Python 코드를 그대로 옮겼고, 회귀 사례와 실제 값 쌍 3,346개에서 엔진과 같은 답을 내는지 대조했습니다.
3. 날짜: 칸이 비어 있는 값
날짜를 연·월·일 세 칸으로 읽으면, 기록마다 채운 칸이 다릅니다. 공시는 '2026-03-26'처럼 세 칸을 다 채웁니다. 기사는 '3월26일'이나 '지난 6월 30일'처럼 연도를 비웁니다. 공고는 '2026. 12월 ~ 2027. 7월'처럼 일을 비우기도 하고, 1단계 추출이 '2000년 12월 31'처럼 '일' 자를 잘라 오기도 합니다.
비교 규칙은 단순합니다. 두 값이 모두 아는 칸만 비교합니다. 아는 칸이 하나라도 다르면 다른 값입니다. 아는 칸이 모두 같고 세 칸이 다 채워졌으면 같은 값, 어느 한쪽에 빈 칸이 있으면 덜 자세한 같은 값입니다. '3월26일'은 연도 칸이 비었고 월·일이 '2026-03-26'과 같으니 덜 자세한 같은 값입니다. '3월 31일'은 일이 다르니 다른 값입니다. 연도를 몰라도 다르다는 것은 압니다.
글자 점수로는 이 구분이 안 됩니다. '2026-03-26'과 '3월26일'의 음절 조각 겹침은 0.11이었고, 엔진은 이 둘을 다른 값으로 보았습니다. DART 코퍼스에서 정기 주주총회 날짜를 다룬 기사가 공시 명제를 지지하지 못하고 반박 큐에 쌓인 이유입니다. 반대로 '2026-04-16'과 '2026-4-16'은 0.62로 문턱 0.6을 겨우 넘어 같은 값이 됐습니다. 0이 하나 빠졌을 뿐인데 운에 맡겨진 판정이었습니다.
연도는 앞에서 물려받는다
공고의 기간은 흔히 '2026. 9. 21.(월) ~ 10. 22.(목)'처럼 끝 날짜의 연도를 생략합니다. 이 끝 날짜를 연도 없는 날짜로 읽으면 '2026. 9. 21. ~ 2026. 10. 22.'와 비교할 때 덜 자세한 값이 됩니다. 사람은 그렇게 읽지 않습니다. 끝은 시작의 연도를 물려받습니다. 엔진도 기간 안에서는 그렇게 읽습니다. 요일 괄호 '(월)'은 버리고, '`26.'처럼 작은따옴표로 줄인 연도는 2026으로 풉니다.
여기에 가정이 하나 숨어 있습니다. '`26'을 2026으로 읽는 것은 지금이 21세기라는 가정입니다. 이것이 바로 1999년 전 세계가 수천억 달러를 들여 고친 문제였습니다.
'부터'와 '까지'는 꾸밈말이 아니다
이번 작업에서 가장 아찔했던 발견은 수정이 아니라 회귀 사례를 먼저 쓰다가 나왔습니다. 엔진의 규칙에 따라 고치기 전에 사례를 넣고 실패를 확인하는데, '2024년 4월 1일부터'와 '2024년 4월 1일까지'를 다른 값이라고 적은 사례가 실패했습니다. 고치기 전 엔진은 이 둘을 같은 값으로 보고 있었습니다. 날짜 표기를 ISO로 맞추고 나면 두 값은 '2024-04-01부터'와 '2024-04-01까지'가 되고, 조각 대부분이 겹치기 때문입니다.
시작일과 마감일은 같은 날이어도 다른 값입니다. 신청 '시작'이 4월 1일인 공고와 '마감'이 4월 1일인 공고는 정반대의 안내입니다. 그래서 날짜 뒤의 '부터·이후'는 시작, '까지·마감·이전'은 끝이라는 역할로 읽습니다. 둘 다 역할이 있는데 다르면 다른 값입니다. 한쪽만 역할이 있으면('2000년 12월 31'과 '2000년 12월 31일까지') 덜 자세한 같은 값입니다. 다행히 실제 두 코퍼스에는 같은 날짜가 '부터'와 '까지'로 엇갈린 쌍이 아직 없었습니다. 이 사례는 사고가 나기 전에 막은 것입니다.
반대로 값의 뜻을 바꾸지 않는 말은 버립니다. 조례 시행일이 '이 조례는 2024년 7월 1일부터 시행한다'처럼 문장째 뽑히기도 하고 '2024년 7월 1일부터'처럼 날짜만 뽑히기도 하는데, 앞뒤의 '이 조례는'과 '시행한다'는 시행일이라는 술어가 이미 말하는 내용입니다. 기사의 '지난'·'오는'도 같습니다. 이 틀 말을 떼고 남은 말이 같아야 같은 값입니다. 이 쌍은 글자 점수 0.53으로 충돌이 되어, 「부산광역시 행정기구 설치 조례」의 시행일이 같은 날짜로 '대체'되는 기록을 남기고 있었습니다. 엔진의 건강 신호인 '설명 안 되는 대체' 일곱 건 가운데 하나였습니다.
시각이 붙은 값('2026.11.5.(목) 10:00~17:00')은 이 계층이 다루지 않습니다. 날짜가 같아도 시각이 다르면 다른 값이고, 시각은 날짜보다 표기가 훨씬 제각각이라 별도의 타입으로 다뤄야 합니다. 지금은 다음 단계에 넘깁니다.
4. 나이: 정수 위의 닫힌 구간
나이 범위는 날짜보다 쉽습니다. 나이는 정수이고, 범위는 닫힌 구간 하나로 풀립니다. '만 19세부터 34세까지', '만 19세~34세', '만 19~34세', '19세 이상 34세 이하'는 모두 [19, 34]입니다. 정수라서 '35세 미만'은 '34세 이하'와 같고, '18세 초과'는 '19세 이상'과 같습니다. 끝이 열린 '65세 이상'은 [65, ∞)입니다.
이 사실은 사람에게는 당연하지만, 수를 비교하는 규칙에게는 아닙니다. 지난 수정에서 넣은 수 검사는 두 값의 수 묶음을 비교합니다. '19세 이상 35세 미만'의 수는 {19, 35}이고 '만 19세~34세'의 수는 {19, 34}입니다. 서로를 포함하지 않으니 충돌입니다. 값 타입 계층을 수 검사보다 앞에 둔 이유입니다. 수 검사는 '다른 수는 다른 값'이라는 좋은 어림이지만, 같은 구간을 다른 끝으로 적는 표기 앞에서는 틀립니다.
'만'은 떼고 읽습니다. 2023년 6월 28일부터 시행된 행정기본법 제7조의2와 개정 민법 제158조는 나이를 "출생일을 산입하여 만(滿) 나이로 계산하고, 연수(年數)로 표시한다"고 적었습니다. 흔히 이때 만 나이가 처음 법이 됐다고 알지만, 민법은 그전에도 출생일부터 나이를 셌습니다. 2023년 개정은 그 규칙을 분명히 적고 표시 방법을 통일한 것입니다. 그래서 공공기록에서 '19세'와 '만 19세'는 같은 나이로 읽어도 됩니다. 다만 다른 법령이 '연 나이'를 따로 정한 경우가 있어, 엔진은 '만' 유무를 값의 차이로 보지 않는다는 정도로만 다룹니다.
같은 낱말이 다른 구간을 가리키는 일도 흔합니다. 청년기본법 제3조는 청년을 "19세 이상 34세 이하인 사람"으로 정하면서, 다른 법령과 조례가 연령을 다르게 정하면 그에 따를 수 있다고 덧붙입니다. 부산광역시 청년 기본 조례는 지금 청년을 18세 이상 39세 이하로 정합니다. 예전에는 18~34세였다가 2023년 개정으로 39세까지 늘었습니다. '부산 청년'이라는 같은 말의 값이 바뀐 것입니다.
지원 대상이 '만 19세~34세'에서 '만 19세~39세'로 바뀌었다면 앞 구간은 뒤 구간 안에 들지만 다른 값입니다. 이 점이 날짜와 다릅니다. 날짜의 빈 칸은 '기록이 말하지 않은 것'이지만, 나이 범위의 끝은 '기록이 정한 것'입니다. 39라고 적은 공고는 34라고 적은 공고보다 덜 자세한 것이 아니라, 다른 대상을 정한 것입니다. 그래서 나이 범위에는 '덜 자세한 같은 값'이 없습니다. 같거나 다를 뿐입니다.
5. 의결결과: 통제 어휘와 그 계층
부산시의회 회의록은 같은 안건의 결과를 여러 표기로 적습니다. 운영 1단계 캐시에서 의결결과 값만 세어 보니 '원안 가결' 125번, '원안대로 가결' 106번, '가결' 27번, '수정 가결' 19번, '수정안대로 가결' 18번, '원안대로 채택 가결' 5번이었습니다. 위원장의 심사보고와 의장의 선포, 회의록 요약이 같은 결과를 조금씩 다르게 말하기 때문입니다.
이 표기들은 글자로는 서로 멀었습니다. '원안 가결'과 '원안대로 가결'의 조각 겹침은 0.33, '가결'과 '원안대로 가결'은 0.20이었습니다. 엔진은 이들을 모두 다른 값으로 보았습니다. 회의록은 1인칭 기록이라 공식 문서처럼 옛 값을 닫을 권위가 없어서, 다른 값들이 서로를 닫지도 못하고 나란히 열려 있었습니다. 한 안건에 의결결과가 둘 이상 열린 경우가 134개였습니다.
의결결과는 날짜와 달리 무한한 값이 아니라 정해진 낱말의 집합, 즉 통제 어휘입니다. 그리고 그 낱말들 사이에 위아래가 있습니다. '가결'은 원안대로인지 수정안대로인지 말하지 않은 덜 자세한 표기이고, '원안 가결'과 '수정 가결'은 그 아래 두 갈래입니다. '부결'은 다른 가지입니다. 엔진은 이 표를 (결과, 무엇으로)라는 두 칸으로 적습니다. '원안대로 채택 가결'은 (가결, 원안), '가결'은 (가결, 빈 칸), '부결'은 (부결, 빈 칸)입니다. 그다음은 날짜와 같은 규칙입니다. 아는 칸이 다르면 다른 값, 빈 칸이 있으면 덜 자세한 같은 값입니다.
이 표는 코퍼스에서 실제로 나온 표기를 중심으로, 뜻이 분명한 몇 개(통과·부결·폐기·보류·철회)만 더해 만들었습니다. 사전에 없는 표기('원안 의결', '수정 의결')가 나오면 판단하지 않고 다음 단계로 넘깁니다. 국회는 법률안의 처리 결과를 정해진 범주로 관리합니다. 열린국회정보의 의원 발의 법률안 자료에 실린 값은 원안가결, 수정가결, 대안반영폐기, 수정안반영폐기, 부결, 폐기, 임기만료폐기, 철회 여덟 가지뿐입니다. 21대 국회의 의원 발의 법률안 23,655건이 이 여덟 칸에 정확히 나뉘어 들어가고, 그 가운데 가장 많은 것은 임기만료폐기(16,032건)입니다. 지방의회 회의록의 말투는 이보다 훨씬 자유로워서, 국회의 범주를 그대로 들여올 수는 없고 표기를 범주로 묶는 표가 따로 필요합니다. 표에 없는 표기를 찾는 일은 9절에서 다시 말하겠지만 판정 모델에 맡기기 좋은 일입니다.
6. 기간과 기간 사이의 열세 가지 관계 (1983)
날짜 하나가 아니라 기간 둘을 비교하면 이야기가 더 복잡해집니다. 1983년 제임스 앨런은 「시간 구간에 대한 지식 유지하기」라는 논문에서, 순서 있는 두 구간이 놓일 수 있는 방식을 모두 셌습니다. A가 B보다 앞서거나(before), 맞닿거나(meets), 겹치거나(overlaps), 함께 시작하거나(starts), B 안에 들거나(during), 함께 끝나거나(finishes), 같거나(equals). 같음을 뺀 여섯 관계에는 뒤집은 짝이 있어서 모두 열세 가지입니다. 흔히 '일곱 개와 그 역 일곱 개'로 기억하지만, 같음은 자기 자신이 역이므로 7 + 6입니다.
앨런의 관계는 인공지능이 시간에 대해 추론할 때 쓰는 기본 어휘가 됐습니다. 그런데 사실탐색기에 필요한 것은 관계 이름이 아닙니다. 아래 위젯에서 막대를 움직여 보면, 같은 그림이 질문에 따라 다른 답이 된다는 것을 볼 수 있습니다.
공고의 신청기간 '9월 21일 ~ 10월 22일'이 '9월 21일 ~ 10월 7일'로 바뀌었다면, 앨런의 말로는 뒤 기간이 앞 기간과 '함께 시작해 그 안에 듭니다'(starts). 하지만 값으로는 기간이 바뀐 것이고, 새 공고가 옛 값을 닫아야 합니다. 기간이 값일 때는 열세 관계 가운데 같음 하나만 같은 값입니다.
반대로 '10월 중'이라는 말과 '10월 17일'은 앨런의 말로 '안에 듦'(during)이고, 이때는 어긋남이 아닙니다. '10월 중'은 그날을 덜 자세히 말한 것일 수 있습니다. 같은 관계가 하나는 충돌이고 하나는 덜 자세한 같은 값입니다. 차이는 그림이 아니라 그 값이 무엇을 말하려는가에 있습니다. 앞의 기간은 기록이 정한 범위이고, 뒤의 '10월 중'은 기록이 정밀하게 말하지 않은 하루입니다.
글자만 봐서는 이 둘을 가르기 어렵습니다. 그래서 사실탐색기는 같은 모양끼리만 판정합니다. 기간은 기간과, 날짜 하나는 날짜 하나와만 비교합니다. 기간의 시작과 끝을 각각 날짜로 비교해 둘 다 같으면 같은 값, 하나라도 다르면 다른 값입니다. 기간과 날짜 하나가 만나면 판단하지 않습니다. 지난 글에서 "포함은 같음이 아니다"라고 한 것은 이 중 앞의 경우, 즉 범위 값 이야기였습니다. 이번에 엔진에 넣으면서 나머지 반쪽인 '덜 자세히 말한 값'에 이름을 붙인 것입니다.
7. A = B, B = C, 그런데 A ≠ C
'덜 자세한 같은 값'에는 함정이 하나 있습니다. 이행적이지 않다는 것입니다.
'가결'은 '원안 가결'과 어긋나지 않습니다. '가결'은 '수정 가결'과도 어긋나지 않습니다. 그렇다고 '원안 가결'과 '수정 가결'이 같지는 않습니다. 같음은 A = B이고 B = C이면 A = C인 관계지만, '어긋나지 않음'은 그렇지 않습니다.
푸앵카레의 물리적 연속체 (1902)
이 역설에는 오래된 이름이 있습니다. 앙리 푸앵카레는 1902년 『과학과 가설』에서 감각 실험 결과를 이렇게 적었습니다. 10그램 추 A와 11그램 추 B는 똑같이 느껴지고, B는 12그램 추 C와도 구별되지 않는데, A와 C는 쉽게 구별된다. 그래서 실험의 날것 결과는 "A = B, B = C, A < C"이고, 푸앵카레는 이것을 '물리적 연속체의 공식'이라고 불렀습니다. 수학의 등호와 감각의 '같다'는 다른 관계라는 것입니다.
루스의 커피 401잔 (1956)
경제학자 던컨 루스는 1956년 논문에서 같은 현상을 선호의 문제로 옮겼습니다. 각설탕 한 개 넣은 커피를 다섯 개 넣은 커피보다 좋아하는 사람이 있다고 합시다. 각설탕 하나 무게의 1/100씩 설탕을 늘린 커피 401잔을 준비하면, 이 사람은 이웃한 두 잔 사이에서는 차이를 못 느끼지만, 첫 잔과 마지막 잔 사이에서는 분명히 첫 잔을 고릅니다. 이웃끼리는 '같은 맛'인데, 그 사슬의 끝은 '다른 맛'입니다. 루스는 이런 무차별 관계를 다루는 구조에 반순서(semiorder)라는 이름을 붙였습니다.
수학자 크리스토퍼 지먼은 1962년 뇌와 시지각의 위상을 다룬 글에서, 반사적이고 대칭적이지만 이행적이지 않은 관계로 이루어진 공간을 허용 공간(tolerance space)이라고 불렀습니다. 문자열 유사도도 같은 성질을 가집니다. 'A와 B가 0.6 넘게 비슷하고 B와 C가 0.6 넘게 비슷해도' A와 C는 비슷하지 않을 수 있습니다. 사실탐색기의 '덜 자세한 같은 값'도 이 계보에 있습니다.
엔진에서는 어떻게 터지나
AGS는 새 클레임이 들어오면 같은 속성의 기존 명제와 값을 비교해, 어긋나지 않으면 그 명제에 근거로 붙입니다. 이때 명제의 대표값하고만 비교하면 사슬이 생깁니다. '가결' 명제에 '원안 가결'이 붙고, 다음에 온 '수정 가결'도 대표값 '가결'과 어긋나지 않으니 붙습니다. 원안 가결과 수정 가결이 한 명제의 근거가 됩니다.
그래서 엔진은 '덜 자세한 같은 값'으로 붙은 클레임의 표기를 명제의 인증서에 남겨 둡니다. 다음 값은 대표값뿐 아니라 그 표기들과도 맞아야 붙습니다. '수정 가결'은 붙은 '원안 가결'과 다르므로 붙지 못하고 새 명제가 되며, 권위 조건을 통과하면 옛 명제를 닫습니다. 연도 없는 날짜도 같습니다. '3월 26일' 명제에 '2026-03-26'이 붙으면, 다음에 온 '2025-03-26'은 붙지 못합니다. 이 동작을 검사하는 시험(test_refines_is_not_transitive)을 함께 넣었습니다.
한계도 있습니다. 명제의 대표값은 처음 들어온 값 그대로입니다. '3월 26일'이 먼저 들어오고 '2026-03-26'이 나중에 붙으면, 화면에는 덜 자세한 '3월 26일'이 보입니다. 더 자세한 값으로 대표값을 바꾸는 일은 명제 id·판본 규칙과 얽혀 있어 이번에는 하지 않았습니다.
8. 실측: 열 쌍이 바꾼 136개
운영 1단계 캐시를 그대로 두고 전체 파이프라인을 두 번 돌렸습니다. 부산 공적 기록 362건(combined@v4)과 DART 공시·기사 2,851건(combined@v1)입니다. 바뀐 것은 C3의 판정 하나뿐입니다. 실행 중에 C3가 불린 값 쌍을 모두 기록해 보니, 중복을 빼고 부산 2,105쌍, DART 1,212쌍이었습니다.
판정이 바뀐 쌍은 열 개, 모두 '충돌 → 같음'
3,317쌍 가운데 판정이 바뀐 쌍은 부산 8개, DART 2개였습니다. 모두 충돌에서 같음(또는 덜 자세한 같음)으로 바뀌었고, 하나하나 손으로 보아 모두 맞았습니다. 반대 방향, 즉 같음에서 충돌로 바뀐 쌍은 없었습니다. 값 타입이 판정한 쌍은 부산 672개, DART 75개였는데, 대부분(부산 663, DART 72)은 전에도 수 검사가 충돌로 판정하던 다른 날짜들이었습니다. 답은 그대로이고 판정한 층만 바뀌었습니다.
열 개는 적어 보이지만, 같은 표기 쌍이 회의록 수백 곳에 되풀이됩니다. 부산 명제는 2,779개에서 2,643개로 136개 줄었고, 그중 135개가 의결결과였습니다. 의결결과가 둘 이상 열린 안건은 134개에서 1개가 됐습니다. 남은 하나는 '찬성 의원(47인)'이 의결결과로 뽑힌 것으로, 비교가 아니라 1단계 추출의 실수입니다. 속성을 가리지 않고 세면 열린 값이 둘 이상인 열쇠가 320개에서 187개가 됐습니다. 남은 187개는 대부분 제출서류·심의사항 같은 목록 값으로, 한 기록이 여러 값을 함께 말하는 정상적인 공존입니다.
건강 신호: 설명 안 되는 대체 7 → 5
사실탐색기는 '대체'가 일어날 때마다 이유를 붙여 봅니다. 정정 공시가 원 공시를 고쳤는지, 다른 수단(조례 vs 공고)이 바꿨는지, 재공고인지. 이유를 못 붙인 대체는 열쇠나 값 비교의 버그일 가능성이 높아서, 운영 게이트가 이 수를 봅니다. 부산은 7건이었고, 그중 둘이 이번 일과 관련 있었습니다. '이 조례는 2024년 7월 1일부터 시행한다'를 '2024년 7월 1일부터'가 '대체'한 것과, '가결'을 '원안대로 가결'이 '대체'한 것입니다. 둘 다 사라졌고, 남은 5건은 모두 재공고 표지 없이 같은 제목으로 다시 낸 공고입니다. 이것은 값이 아니라 열쇠 쪽 숙제입니다.
DART에서는 반박(리뷰 대기)이 29건에서 27건이 됐습니다. 기사의 '3월26일'과 '지난 6월 30일'이 공시 날짜와 다른 값으로 잡혀 반박 큐에 있던 것이, 이제 공시 명제를 지지합니다. 정정으로 설명되는 대체 261건, 질문 회귀 16/16, 부산 질문 회귀 25/25와 이야기 회귀 4/4는 그대로였습니다.
뜻밖의 발견이 하나 더 있습니다. 사실탐색기에는 값 비교를 비율로 재는 라벨 세트가 있습니다. 같은 값 다른 표기 749쌍, 숫자 하나만 바꾼 585쌍, 실제로 대체된 31쌍, 모두 1,365쌍입니다. 새 계층을 넣은 뒤에도 앞의 두 묶음은 100% 맞았습니다. 그런데 '실제 대체 쌍' 31개 중 2개가 어긋났습니다.
들여다보니 그 두 쌍이 바로 위의 버그였습니다. 이 묶음의 라벨은 엔진이 실제로 대체한 쌍에서 자동으로 '다른 값'을 붙여 만든 것이었습니다. 엔진의 출력으로 만든 라벨은 엔진의 버그를 정답으로 외웁니다. 그 라벨로 재면 버그를 고친 엔진이 점수를 잃습니다. 라벨 세트는 사람이 검수해야 하고, 시스템 출력에서 뽑은 라벨에는 출처를 적어 두어야 합니다. 이 두 라벨은 고쳐야 할 목록에 올렸습니다.
9. 2026년, 판정 모델은 어디에 서야 하나
여기까지 오면 자연스러운 질문이 있습니다. 2026년에 이런 걸 규칙으로 짤 필요가 있나? 작은 언어 모델에게 "두 값이 같은 사실인가"를 물으면 되지 않나?
사실탐색기에는 실제로 그런 판정 모델 자리가 있습니다. 수량이 아닌 두 값을 로컬 모델(qwen3.5:9b)에 묻고, 확신도 0.8 아래면 쓰지 않고 규칙으로 돌아갑니다. 한쪽이 다른 쪽을 품는 쌍은 아예 묻지 않고 '모름'으로 둡니다. 그래서 같은 값 쌍 73개를 이 판정 모델과 더 작은 qwen3.5:4b에 엔진의 프롬프트 그대로 물어봤습니다. 회귀 사례 29쌍과 실제 코퍼스 쌍 44개입니다.
결과는 솔직히 말해 모델 쪽에 좋았습니다. 9B 모델은 73쌍 중 71쌍을 맞혔습니다. '원안 가결'과 '원안대로 가결', '19세 이상 35세 미만'과 '만 19세~34세'를 모두 같은 값이라고 했고, 이유도 그럴듯했습니다. 맥의 로컬 Ollama에서 한 쌍에 평균 0.8초였습니다. 시험지가 모델에 유리했다는 점도 적어 둡니다. '다른 값' 52쌍 중 상당수는 연도가 다른 날짜처럼 쉬운 쌍입니다.
문제는 틀린 두 쌍입니다. 9B 모델은 '2000년 12월 31'과 '2000년 12월 31일까지'를 확신도 0.95로 "A는 특정 날짜, B는 그날까지의 기간이라 범위가 다르다"고 했습니다. '2026-06-30'과 '지난 6월 30일'에는 확신도 0.9로 "A는 미래의 날짜인 반면 B는 과거를 지칭"한다고 했습니다. 두 값 어디에도 오늘이 언제인지는 없습니다. 틀린 답일수록 확신도가 높았고, 이유는 지어낸 것이었습니다. 확신도 문턱 0.8로는 이 둘을 걸러 낼 수 없습니다. 앞의 쌍은 엔진의 다른 규칙, 즉 한쪽이 다른 쪽을 품으면 묻지 않고 '모름'으로 두는 규칙이 막았습니다. 하지만 '지난 6월 30일'은 그대로 충돌로 쓰였을 것입니다.
4B 모델은 다섯 쌍을 틀렸고, 더 흥미로운 실수도 했습니다. '2026-03-26'과 '3월 31일'을 다른 값이라고 맞혔는데, 이유는 "2026년 3월에는 31일이라는 날짜가 존재하지 않으므로"였습니다. 3월은 31일까지 있습니다. 답은 맞고 이유는 틀렸습니다. '19세 이상 35세 미만'과 '만 19세~34세'에는 "35세를 포함하지 않는 반면 34세까지 포함하므로 범위가 다르다"고 답했습니다. 나이가 정수라는 것을 놓쳤습니다.
코퍼스를 훑어 '원안 의결'·'수정 의결' 같은 새 표기와 그 범주를 제안한다. 사람이 확인하면 표에 넣는다
새 값 타입 찾기
회귀 사례로 규칙을 고정한다
어떤 술어의 값이 날짜인지·기간인지·통제 어휘인지 분류해 다음 타입 후보를 고른다
타입 밖의 문장 값
확신도·포함 규칙으로 걸러 쓴다
제안한다. 단 근거 문장과 함께, 문턱 아래는 리뷰 큐로
코드는 판정하는 쌍이 적은 대신, 판정한 쌍에서는 같은 입력에 늘 같은 답을 내고 그 이유를 칸 단위로 보여 줍니다. 1단계 추출에서 이미 LLM이 값을 뽑았는데 비교까지 LLM이 하면, 같은 종류의 실수가 두 번 겹칩니다. 사실탐색기의 첫 원칙 "LLM은 제안하고, 코드가 결정한다"는 모델이 못해서가 아니라, 틀릴 때 어떻게 틀리는지 알 수 있어야 옛 값을 닫는 일을 맡길 수 있기 때문입니다.
10. 남은 일과 이 결과의 한계
대표값은 처음 값 그대로입니다. 덜 자세한 값이 먼저 오면 화면에 덜 자세한 값이 보입니다. 붙은 표기 중 가장 자세한 것을 보여 주는 일이 남았습니다.
시각이 붙은 값은 다루지 않습니다. '10:00~17:00' 같은 값은 다음 단계에 넘깁니다. 시각은 별도 타입이 필요합니다.
'`26'은 2026이라고 가정합니다. 21세기 기록이라는 가정입니다. 1990년대 조례 부칙을 같은 방식으로 줄여 쓴 기록이 들어오면 틀립니다.
'지난 6월 30일'의 '지난'은 버립니다. 기사가 작년 6월 30일을 말했을 수도 있습니다. 연도 칸을 비워 두므로 다른 연도의 공시와 묶이지는 않지만, 기사 날짜로 연도를 채우는 일은 하지 않았습니다.
틀 말 목록은 짧습니다. '이 조례는'·'시행한다'·'지난'·'오는' 정도입니다. '공포한 날부터'와 '공포한 날부터 시행한다'(글자 점수 0.56, 충돌)처럼 날짜가 없는 시행일 문장은 이 계층 밖이라 여전히 글자 점수가 판정합니다.
의결결과 표는 부산 회의록에서 나온 표기 위주입니다. 다른 의회의 말투가 들어오면 표를 넓혀야 하고, 그 일에 판정 모델이 쓸모 있습니다(9절).
실측은 두 코퍼스, 한 날의 것입니다. 판정이 바뀐 열 쌍은 모두 맞았지만, 열 쌍은 작은 표본입니다. 회귀 사례 17개(ags-13~29)가 앞으로의 변경을 지킵니다.
11. 실무 체크리스트: 두 값이 같은지 물을 때
이 값의 타입은 무엇인가. 날짜·기간·나이 범위·금액·통제 어휘라면 글자 유사도 전에 칸으로 읽는다.
어느 칸을 알고 어느 칸을 모르는가. 모르는 칸은 0이나 기본값으로 채우지 말고 비워 둔다. Y2K와 고려대 졸업증명서가 그 대가다.
답에 '덜 자세한 같은 값'과 '판단하지 않음' 칸이 있는가. 같다/다르다 두 칸만 있으면 빈 칸이 있는 값은 어느 쪽으로든 틀린다.
꾸밈말인가, 역할인가. '이 조례는'은 버려도 되지만 '부터'와 '까지'는 버리면 안 된다.
범위의 끝은 기록이 정한 것인가, 말하지 않은 것인가. 정한 끝이 다르면 다른 값이다(19~34세 vs 19~39세).
'어긋나지 않음'을 같음처럼 이어 붙이고 있지 않은가. 붙은 표기를 남기고 다음 값을 그것들과도 맞춘다.
라벨은 어디서 왔는가. 시스템 출력에서 뽑은 라벨은 그 시스템의 버그를 정답으로 담고 있을 수 있다.
맺으며: 해상도는 값의 일부다
'3월 26일'과 '2026-03-26'은 같은 값이 아닙니다. 다른 값도 아닙니다. 한쪽이 덜 말한 값입니다. 사람은 이 관계를 의식하지 않고 다루지만, 같다와 다르다 두 칸만 가진 프로그램에게는 이 관계를 적을 자리가 없습니다. 자리가 없으면 프로그램은 글자 조각의 겹침 같은 대리 지표로 둘 중 하나를 고르고, 그 대리 지표는 '원안 가결'과 '원안대로 가결'을 갈라놓고 '부터'와 '까지'를 붙여 놓습니다.
이번 수정은 그 자리를 만든 일입니다. 바꾼 판정은 열 쌍뿐이었지만, 한 안건에 의결결과가 둘씩 열려 있던 134곳이 하나로 정리됐습니다. 그리고 그 과정에서 엔진의 출력으로 만든 라벨이 엔진의 버그를 정답으로 외우고 있다는 것, 9B 모델이 틀릴 때 가장 자신만만하다는 것도 확인했습니다.
다음 숙제는 남은 '설명 안 되는 대체' 다섯 건, 재공고 표지 없이 다시 낸 공고들입니다. 이것은 값이 아니라 같은 공고인가, 즉 지난 글의 네 질문 가운데 '같은 대상인가'의 문제입니다.
참고문헌
James F. Allen, "Maintaining Knowledge about Temporal Intervals", Communications of the ACM 26(11), 1983, pp. 832–843. doi:10.1145/182.358434
R. Duncan Luce, "Semiorders and a Theory of Utility Discrimination", Econometrica 24(2), 1956, pp. 178–191.
Henri Poincaré, La Science et l'Hypothèse, Flammarion, 1902, 2장 「수학적 크기와 경험」의 '물리적 연속체'. 위키문헌 프랑스어판.
E. C. Zeeman, "The topology of the brain and visual perception", in M. K. Fort Jr. (ed.), Topology of 3-Manifolds and Related Topics, Prentice-Hall, 1962, pp. 240–256.
U.S. Senate Special Committee on the Year 2000 Technology Problem, Y2K Aftermath – Crisis Averted: Final Committee Report, 2000-02-29.
Microsoft Learn, "Excel incorrectly assumes that the year 1900 is a leap year".
ISO 8601:1988 (첫 판), ISO 8601-2:2019 Date and time — Representations for information interchange — Part 2: Extensions.
Library of Congress, Extended Date/Time Format (EDTF) Specification, 2019-02-04.
R. Saurí, E. Saquete, J. Pustejovsky, Annotating Time Expressions in Spanish: TimeML Annotation Guidelines (TempEval-2010), Barcelona Media TR 2010-02 — TIMEX3 값의 X 자리표시.
Wikibase DataModel, Time 값의 precision(9 연, 10 월, 11 일).
행정기본법 제7조의2, 민법 제158조(2022-12-27 공포, 2023-06-28 시행). 청년기본법 제3조. 부산광역시 청년 기본 조례 제3조. 국가법령정보센터.