27검증 문제
직접 작성한 Bits 인스턴스 고치기
1. 문제와 수정 범위
unpack은 pack이 정한 프로토콜 코드를 거꾸로 되돌려야 합니다. 프로토콜은 Idle에
01, Start에 10, Stop에 11을 할당합니다. starter의 pack은 이 표를 따르지만,
unpack은 다른 대응표를 사용합니다.
unpack 안의 디코딩 분기만 수정하세요. Command 선언, Bits#(Command, 2) instance
머리, pack, 보조 함수 두 개, mkTop은 그대로 둡니다.
Bits#(Command, 2)는 두 함수의 타입과 폭만 검사합니다. 두 분기표가 서로 맞는지는 검사하지
않으므로 starter는 컴파일됩니다. 잘못된 대응은 시뮬레이션에서 다른 명령이 출력되는
증상으로 드러납니다.
2. starter 읽기와 실행 전 예측
Command, instance 머리, pack, unpack, mkTop 순서로 읽어 보세요. pack의 세 분기를
enum label과 2비트 코드의 표로 적고, unpack의 분기를 같은 표에 겹쳐 적습니다.
mkTop의 첫 출력은 인코딩 하나를, 두 번째 출력은 디코딩 하나를 보여 줍니다.
실행을 누르기 전에 두 출력을 예측해 보세요.
| 출력 | 현재 결과 | 요구 결과 |
|---|---|---|
Stop의 코드 | 11 | 11 |
01의 디코딩 | Start | Idle |
첫 출력은 이미 맞고 두 번째 출력만 틀립니다. instance를 찾지 못한 컴파일 오류가 아니라, 두 방향의 대응표가 어긋난 의미 오류입니다. 실행 결과로 이 예측을 확인해 보세요.
3. 최소 수정과 완료 조건
pack의 표를 기준으로 unpack의 분기만 역방향 표로 고치세요. 새 순서를 만들지 말고
기존 인코딩을 그대로 뒤집습니다. 수정을 마치면 다음 계약이 모두 성립해야 합니다.
01,10,11은 각각Idle,Start,Stop으로 디코딩됩니다.- 할당되지 않은
00은Idle로 디코딩됩니다. - 세 명령 모두
unpack(pack(value)) == value가 성립합니다. pack의 코드와 2비트 폭은 바뀌지 않습니다.
수정한 뒤 실행에서 Stop은 계속 11로, 01은 Idle로 출력되어야 합니다. 화면에
보이는 01 하나만 맞추어서는 완료가 아닙니다. 2비트 입력 네 개를 모두 표로 확인하세요.
00은 Idle로 정규화되므로, 디코딩한 값을 다시 pack하면 00이 아니라 01이 됩니다.
4. 단계형 힌트
힌트 1: 어긋난 계약 찾기
타입클래스는 변환 함수의 타입과 폭을 고정합니다. 프로토콜은 여기에 두 함수가 하나의
대응을 반대 방향으로 표현해야 한다는 조건을 더합니다. enum 선언 순서가 아니라 두
대응표를 비교해 보세요.
힌트 2: 수정 위치 좁히기
프로토콜과 충돌하는 곳은 unpack의 case뿐입니다. 할당된 세 코드를 먼저 각 명령과
연결하세요.
힌트 3: 미할당 코드 처리하기
2비트 코드 네 개 가운데 하나는 어느 명령에도 할당되지 않았습니다. 나머지 경우를 받는
분기가 이 코드를 맡아 요구된 안전한 값을 반환하게 하세요. 디코더에 맞춰 pack을 고치지는
않습니다.
5. 추가 실험
수정을 마친 뒤 mkTop이 디코딩하는 입력만 잠시 10으로 바꿔 보세요. Start가 출력될
것이라고 먼저 예측하고, 실행으로 확인한 뒤 입력을 01로 되돌리세요. 01만 예외로
처리한 수정과 대응표 전체를 고친 수정은 이 실험에서 결과가 갈립니다.