(P⟹Q)∧(¬P⟹¬Q)가 의미하는 것
페이스북을 눈팅 하나다 재미있는 페친님의 포스팅을 하나 보게 되었습니다. 포스팅에는 아래의 사진이 하나 담겨 있었는데요. 전형적인 if-else 구문입니다.
구문을 해석해보면 "만약 게임이 MapleStory Worlds라면 500만 원의 수입이 생기고, 그렇지 않다면 수입이 0원이다." 정도로 해석해 볼 수 있겠습니다.
우리가 프로그래밍을 시작할 때 학습 초반부에 배우는 것이 바로 if-else 구문입니다. 그런데 이 조건 분기문을 조금만 논리학적(형식논리) 관점에서 보면
(P⟹Q)∧(¬P⟹*),
이런 구조가 쉽게 떠오르죠. 더욱 흥미로운 것은, 많은 경우 코드를 작성하면서 실제로는 위의 사진의 코드처럼
형태를 자연스럽게 활용하게 된다는 점입니다. 형식논리에서 이는 곧
("P와 Q는 동치")와 같은 뜻입니다.
형식논리에서
이 두 문장을 동시에 만족한다는 것은, 결국 "P가 참일 때와 Q가 참일 때가 정확히 일치한다."는 뜻입니다. 즉,
프로그래밍 코드로 보자면, 예컨대
if (P) then
Q (예: income = 5000000)
else
not Q (예: income = 0)
end
처럼 작성하면, 코드는 "P가 참이면 반드시 Q가 성립하도록 만들고, P가 거짓이면 언제나 Q를 성립하지 않게(¬Q) 만든다"는 의도를 명시적으로 담게 됩니다. 그렇게 하면
라는 논리 구조를 그대로 코드에 표현하게 되지요.
이런 사실을 알게 되면, 프로그래밍 101에서 배우는 조건 분기문 안에 의외로 깊은 형식논리의 아름다움이 숨어 있음을 새삼 느낄 수 있습니다.
라는 말은, "항상 P와 Q가 같은 진리값(참/거짓)을 지닌다”는 뜻입니다. 특히 코드에서라면 P가 거짓일 때 Q가 절대 참이 될 수 없도록 통제하는 것이죠. 다시 말해, P가 아니면 Q도 아니다가 성립하도록 if-else문을 작성하는 것입니다.
물론, 실제 절차형 프로그래밍에서는 "조건이 아니면 굳이 Q를 배제(¬Q)할 필요는 없습니다. 즉, else 블록에서 다른 작업을 수행 하기도 합니다. 그런 경우 코드가 (P⟹Q)만 만족하고 (¬P⟹¬Q)는 보장하지 않을 수도 있습니다. 그래서 (P⟹Q)∧(¬P⟹¬Q) 형태로 코드를 작성하려면 일반적으로 else 블록 안에 ¬Q를 명시적으로 작성해줘야 합니다.
함수형 프로그래밍(특히 하스켈, Coq 등)은 타입 이론과 수학적 논리에 근거해 있으며, 참조 투명성(referential transparency)이나 불변성(immutability) 같은 논리적 제약을 적극적으로 활용합니다.
이러한 제약들은 코드를 분석·추론할 때 논리적으로 증명하듯 접근할 수 있게 해 주고,
그 과정에서 버그를 줄이거나 최적화를 가능하게 만들기도 한다고 합니다.
"형식논리를 직접 의식하며 코딩하는 게 얼마나 유용할까?"라고 의아할 수 있지만, 이미 많은 함수형 언어 커뮤니티에서는 '코드의 안전성과 효율을 높인다’는 장점을 실감하고 있다고 있습니다. 저는 아직 함수형 프로그래밍에 대한 직접적인 경험은 없지만 항상 형식논리를 사용해야 하는 수학도 입장에서 충분히 매력적으로 보이는 요소이기는 합니다.
정리하자면, 우리는 if-else 구문을 통해 "(P ⟹ Q)와 (¬P ⟹ ¬Q)"가 동시에 성립하는 경우, 논리학적으로 P ⟺ Q(동치) 임을 자연스럽게 구현할 수 있음을 보았습니다. 이런 사실은 단순한 조건 분기문의 내부에도 형식논리의 정교함이 숨어 있음을 시사합니다. 이처럼 형식논리를 코드와 밀접하게 연계하여 생각하면, 프로그래밍은 더 이상 '단순 명령어 나열'이 아니라 '수학적 사고의 연장선'이라는 사실을 깨닫게 됩니다.
마지막으로 혹시 형식논리를 공부 해 보고 싶은 분들은 아래 유튜브 lecture 시리즈를 추천 합니다.
Introduction to Formal Logic
https://youtu.be/qL6HMPOYlVs?si=Uzh0bQ78lgtEsr7K