shopkeeper/korean_wiki_content_only_120125 huggingface dataset:
조건부 추론을 연구하는 심리학자들에 의해 유사한 불일치가 관찰되었는데, 예를 들어 악명 높은 웨이슨 선택 과제 연구에서 참가자의 10% 미만이 실질 조건문에 따라 추론했다. 일부 연구자들은 이 결과를 참가자들이 규범적인 추론 법칙을 따르지 못한 실패로 해석한 반면, 다른 연구자들은 참가자들이 비고전적 법칙에 따라 규범적으로 추론한다고 해석한다.
연경도약대암장(硏經跳躍臺巖嶂, Yeongyeong Doyakdae Rocky Climb), 대구 연경동 도약대 암장은 대구광역시 동구 연경동 지역에 위치한 암벽등반 암장이며 중생대 백악기의 퇴적암 신라 역암층으로 구성된 자연 절벽이다. 도시에 인접한 암장으로 1990년 개척을 시작해 현재까지 운영되고 있다.
1990년 대구 극등회는 동화천 하천변에 위치한 이 절벽을 '연경동 도약대'로 처음 명명하였다. 이후 여러 산악회에서 추가로 루트를 개척하여 현재는 총 51개 루트가 개설되어 있다. 도시에서 가까워 많은 등반자가 찾으며 여름에는 발전기로 불을 밝혀 야간 등반도 실시한다.
연경도약대암장은 가장 좌측부터 도약대, 용바위1, 용바위2, 고바위 4개 암장으로 구성되며 이 중 도약대 바위 이름을 따서 통상적으로 연경 도약대라고 지칭한다. 총 51개 루트가 존재하며 루트의 난이도는 대체로 5.10~5.11급으로 초·중급이다.
연경도약대암장은 대구광역시에 있어 시내와 가까와 접근이 매우 편리하며 연경체육공원 주차장(도로명주소: 대구광역시 북구 동화천로 330) 뒤쪽 길로 접근하거나 연경공원(도로명주소: 대구 북구 동화천로 333)에서 동화천 하천 산책로를 따라 접근할 수 있다. 연경체육공원 주차장에는 20여 대가 주차할 수 있고 화장실이 있으며 이 주차장 뒤쪽에서 연경도약대암장으로 접근할 수 있는 길이 있다.
연경도약대암장은 중생대 백악기의 퇴적암 신라 역암층 지층으로 구성된다. 신라 역암층은 경상 누층군의 역암 지층으로 연경도약대암장에서 아래 사진과 같이 역암의 자갈들을 관찰할 수 있다. 대구 지질도폭(1928)에 의하면 신라 역암층은 주로 역암으로 구성되며 두께는 200~600 m이다. 주향은 북동, 경사는 남동으로 10 내지 30°이다. 대구광역시 북부의 신라 역암층은 대체로 잔자갈역암(pebble)에 속하며 대부분의 자갈은 아원형이다. 자갈은 주로 규암, 사암, 편마암, 응회암으로 구성되며 셰일, 석영맥, 화강암, 규장암, 처트의 역이 소량 포함된다. 이 역들의 근원지는 퇴적분지의 북서쪽에 위치한 것으로 추정된다.
컴퓨터 프로그래밍에서 프로그램은 프로그래밍 언어 사양이 특정 요구 사항을 강제하지 않는 코드를 포함하거나 실행할 때 미정의 동작(undefined behavior, UB)을 보인다. 이는 언어 사양이 결과를 규정하지 않는 미지정 동작과, 컴퓨팅 플랫폼의 다른 구성 요소(예: ABI 또는 트랜슬레이터 문서)의 문서를 따르는 구현 정의 동작과는 다르다.
C 프로그래밍 커뮤니티에서 미정의 동작은 컴파일러가 "코에서 악마가 날아가게" 하는 등 원하는 모든 것을 할 수 있도록 허용한다고 설명한 comp.std.c 게시물에 따라 유머러스하게 "코 악마"라고 불리기도 한다.
일부 프로그래밍 언어는 프로그램 실행 중에 미정의 동작이 발생하지 않는 한, 소스 코드와 다른 방식으로 작동하거나 심지어 다른 제어 흐름을 가질 수 있도록 허용한다. 미정의 동작은 프로그램이 충족해서는 안 되는 조건 목록의 이름이다.
C의 초기 버전에서 미정의 동작의 주요 이점은 다양한 기계에 대해 성능이 좋은 컴파일러를 생성한다는 것이었다. 특정 구문은 기계별 기능에 매핑될 수 있었고, 컴파일러는 언어에 의해 부과된 의미론과 일치하도록 부작용을 조정하기 위해 런타임에 추가 코드를 생성할 필요가 없었다. 프로그램 소스 코드는 특정 컴파일러와 지원할 컴퓨팅 플랫폼에 대한 사전 지식을 가지고 작성되었다.
그러나 플랫폼의 점진적인 표준화로 인해 이러한 이점은 특히 C의 최신 버전에서 줄어들었다. 이제 미정의 동작 사례는 일반적으로 코드의 모호하지 않은 소프트웨어 버그를 나타내는데, 예를 들어 배열의 범위를 벗어나 인덱싱하는 경우이다. 정의에 따르면 런타임은 미정의 동작이 결코 발생하지 않는다고 가정할 수 있으므로, 일부 유효하지 않은 조건을 확인할 필요가 없다. 컴파일러의 경우, 이는 또한 다양한 프로그램 변환이 유효해지거나, 그 정확성 증명이 단순화된다는 것을 의미한다. 이는 프로그램 상태가 그러한 조건을 결코 충족하지 않는다는 가정에 의존하는 다양한 종류의 최적화를 가능하게 한다. 컴파일러는 프로그래머에게 알리지 않고 소스 코드에 있었을 수 있는 명시적 검사를 제거할 수도 있다. 예를 들어, 발생 여부를 테스트하여 미정의 동작을 감지하는 것은 정의상 작동이 보장되지 않는다. 이로 인해 휴대용 오류 방지 옵션을 프로그래밍하기 어렵거나 불가능하다(일부 구문의 경우 비휴대용 솔루션이 가능하다).
현재 컴파일러 개발은 일반적으로 범용 데스크톱 및 랩톱 시장(예: amd64)에서 주로 사용되는 플랫폼에서도 마이크로 최적화를 중심으로 설계된 벤치마크로 컴파일러 성능을 평가하고 비교한다. 따라서 미정의 동작은 컴파일러 성능 향상을 위한 충분한 여지를 제공하는데, 특정 소스 코드 문의 소스 코드가 런타임에 어떤 것이든 매핑될 수 있기 때문이다.
C 및 C++의 경우, 컴파일러는 이러한 경우에 컴파일 시간 진단을 제공할 수 있지만 필수는 아니다. 구현은 디지털 논리의 Don't-care term과 유사하게 이러한 경우에 무엇을 하든 올바른 것으로 간주된다. 컴파일러 구현이 이러한 경우에 진단을 발행할 수 있지만, 미정의 동작을 호출하지 않는 코드를 작성하는 것은 프로그래머의 책임이다. 오늘날 컴파일러는 이러한 진단을 활성화하는 플래그를 가지고 있다. 예를 들어, codice_1는 gcc 4.9 및 클랭에서 "미정의 동작 새니타이저"(UBSan)를 활성화한다. 그러나 이 플래그는 기본값이 아니며, 이를 활성화하는 것은 코드를 빌드하는 사람의 선택이다.
특정 상황에서는 미정의 동작에 대한 특정 제한이 있을 수 있다. 예를 들어, CPU의 명령어 집합 사양은 일부 명령어 형식의 동작을 미정의로 둘 수 있지만, CPU가 메모리 보호를 지원하는 경우 사양에는 사용자 접근 가능한 어떤 명령어("user-accessible instruction")도 운영체제의 보안에 구멍을 낼 수 없다는 일반적인 규칙이 포함될 것이다. 따라서 실제 CPU는 그러한 명령어에 응답하여 사용자 레지스터를 손상시키는 것이 허용되지만, 예를 들어 관리자 모드로 전환하는 것은 허용되지 않는다.
툴체인 또는 런타임이 소스 코드에서 발견되는 특정 구문이 런타임에 사용 가능한 특정 잘 정의된 메커니즘에 매핑된다고 명시적으로 문서화하는 경우, 런타임 플랫폼도 미정의 동작에 대한 일부 제한 또는 보장을 제공할 수 있다. 예를 들어, 인터프리터는 언어 사양에서 미정의된 일부 작업에 대해 특정 동작을 문서화할 수 있지만, 동일한 언어의 다른 인터프리터 또는 컴파일러는 그렇지 않을 수 있다. 컴파일러는 특정 ABI를 위한 실행 코드를 생성하여 컴파일러 버전에 따라 semantic gap을 채운다. 해당 컴파일러 버전의 문서와 ABI 사양은 미정의 동작에 대한 제한을 제공할 수 있다. 이러한 구현 세부 사항에 의존하면 소프트웨어는 휴대성이 없게 되지만, 소프트웨어가 특정 런타임 외부에서 사용되지 않아야 한다면 휴대성은 문제가 되지 않을 수 있다.
미정의 동작은 프로그램 충돌을 일으킬 수 있으며, 데이터의 침묵 손실 및 잘못된 결과 생성과 같이 감지하기 더 어렵고 프로그램이 정상적으로 작동하는 것처럼 보이게 하는 오류를 발생시킬 수도 있다.
오류 프로그램.
프로그래밍 언어 설계에서 오류 프로그램은 의미론이 잘 정의되지 않았지만, 언어 구현이 컴파일 시간 또는 실행 시간 모두에서 오류를 알릴 의무가 없는 프로그램이다. 예를 들어 에이다에서는 다음과 같다.
조건을 "오류"로 정의하는 것은 언어 구현이 잠재적으로 비용이 많이 드는 검사(예: 전역 변수가 서브루틴 매개변수와 동일한 객체를 참조하는지 여부)를 수행할 필요는 없지만, 프로그램의 의미론을 정의할 때 조건이 참이라는 것에 의존할 수 있음을 의미한다.
작업을 미정의 동작으로 문서화하면 컴파일러가 이 작업이 규칙을 준수하는 프로그램에서는 결코 발생하지 않을 것이라고 가정할 수 있다. 이는 컴파일러에 코드에 대한 더 많은 정보를 제공하며, 이 정보는 더 많은 최적화 기회로 이어질 수 있다.
C 언어의 예시:
int foo(unsigned char x) {
int value = 2147483600; /* assuming 32-bit int and 8-bit char */
if (value &lt; 2147483600) {
bar();
codice_2의 값은 음수가 될 수 없으며, 부호 있는 정수 오버플로가 C에서 미정의 동작이라는 점을 고려할 때, 컴파일러는 codice_3이 항상 거짓일 것이라고 가정할 수 있다. 따라서 codice_4 문의 테스트 표현식에 부작용이 없고 조건이 결코 충족되지 않으므로, 함수 codice_5 호출을 포함한 codice_4 문은 컴파일러에 의해 무시될 수 있다. 따라서 코드는 의미론적으로 다음과 동일하다.
만약 컴파일러가 부호 있는 정수 오버플로가 래핑 동작을 가진다고 가정해야 했다면, 위의 변환은 유효하지 않았을 것이다.
코드가 더 복잡하고 인라이닝과 같은 다른 최적화가 이루어질 때, 이러한 최적화는 사람이 알아차리기 어려워진다. 예를 들어, 다른 함수가 위 함수를 호출할 수 있다.
void run_tasks(unsigned char* ptrx) {
z = foo(*ptrx);
while (*ptrx &gt; 60) {
run_one_task(ptrx, z);
컴파일러는 값 범위 분석을 적용하여 여기에서 codice_7 루프를 최적화할 수 있다. codice_8를 검사하여 codice_9가 가리키는 초기 값이 47을 초과할 수 없다는 것을 안다(47을 초과하면 codice_8에서 미정의 동작을 유발할 수 있기 때문이다). 따라서 codice_11의 초기 검사는 규칙을 준수하는 프로그램에서 항상 거짓이 될 것이다. 더 나아가, codice_12 결과가 이제 사용되지 않고 codice_8에 부작용이 없으므로, 컴파일러는 codice_14를 즉시 반환하는 빈 함수로 최적화할 수 있다. codice_8가 별도로 컴파일된 객체 파일에 정의되어 있다면 codice_7 루프의 사라짐은 특히 놀라울 수 있다.
부호 있는 정수 오버플로를 미정의로 허용하는 또 다른 이점은 변수의 값을 소스 코드의 변수 크기보다 큰 프로세서 레지스터에 저장하고 조작할 수 있다는 것이다. 예를 들어, 소스 코드에 지정된 변수의 타입이 기본 레지스터 너비보다 좁은 경우(예: 64비트 머신에서 codice_17, 일반적인 시나리오), 컴파일러는 코드의 정의된 동작을 변경하지 않고 생성하는 기계어에서 해당 변수에 대해 부호 있는 64비트 정수를 안전하게 사용할 수 있다. 프로그램이 32비트 정수 오버플로 동작에 의존했다면, 컴파일러는 64비트 머신용으로 컴파일할 때 추가 로직을 삽입해야 했을 것이다. 왜냐하면 대부분의 기계 명령어의 오버플로 동작은 레지스터 너비에 따라 달라지기 때문이다.
미정의 동작은 또한 컴파일러와 정적 프로그램 분석 모두에서 더 많은 컴파일 시간 검사를 허용한다.
C 및 C++ 표준에는 미정의 동작의 여러 형태가 있으며, 이는 컴파일러 구현의 자유도를 높이고 컴파일 시간 검사를 가능하게 하지만, 존재할 경우 미정의 런타임 동작을 초래한다. 특히 ISO C 표준에는 미정의 동작의 일반적인 원인을 나열한 부록이 있다. 더욱이 컴파일러는 미정의 동작에 의존하는 코드를 진단할 의무가 없다. 따라서 프로그래머, 심지어 숙련된 프로그래머조차도 실수로 또는 단순히 수백 페이지에 달하는 언어 규칙에 익숙하지 않아 미정의 동작에 의존하는 경우가 흔하다. 이로 인해 다른 컴파일러 또는 다른 설정이 사용될 때 드러나는 버그가 발생할 수 있다. 클랭 새니타이저와 같은 동적 미정의 동작 검사를 활성화하여 테스트 또는 퍼징을 수행하면 컴파일러 또는 정적 분석기가 진단하지 못하는 미정의 동작을 포착하는 데 도움이 될 수 있다.
미정의 동작은 소프트웨어의 보안 취약점으로 이어질 수 있다. 예를 들어, 주요 웹 브라우저의 버퍼 오버플로 및 기타 보안 취약점은 미정의 동작으로 인한 것이다. 2008년 GCC 개발자들이 미정의 동작에 의존하는 특정 오버플로 검사를 생략하도록 컴파일러를 변경했을 때, CERT는 최신 버전의 컴파일러에 대해 경고를 발행했다. Linux Weekly News는 PathScale C, 마이크로소프트 비주얼 C++ 2005 및 여러 다른 컴파일러에서도 동일한 동작이 관찰되었다고 지적했다. 이 경고는 나중에 다양한 컴파일러에 대해 경고하도록 수정되었다.
C 및 C++의 예시.
C에서 미정의 동작의 주요 형태는 크게 다음과 같이 분류할 수 있다. 공간 메모리 안전 위반, 시간 메모리 안전 위반, 정수 오버플로, 엄격한 별칭 위반, 정렬 위반, 순서 없는 수정, 데이터 경합, 그리고 I/O를 수행하지도 종료하지도 않는 루프.
C에서 자동 변수를 초기화하기 전에 사용하면 미정의 동작이 발생하며, 정수 0으로 나누기, 부호 있는 정수 오버플로, 정의된 범위 밖의 배열 인덱싱(버퍼 오버플로 참조) 또는 널 포인터 역참조도 마찬가지이다. 일반적으로 미정의 동작의 모든 인스턴스는 추상 실행 기계를 알 수 없는 상태로 남겨두고 전체 프로그램의 동작을 미정의 상태로 만든다.
문자열 리터럴이 일반적으로 읽기 전용 메모리에 저장되기 때문에, 이를 수정하려고 시도하면 미정의 동작이 발생한다.&lt;ref name="C++03 2.13.4/2"&gt;ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages – C++ §2.13.4 String literals [lex.string] para. 2&lt;/ref&gt;
char* p = "wikipedia"; // valid C, deprecated in C++98/C++03, ill-formed as of C++11
p[0] = 'W'; // undefined behavior
정수 0으로 나누기는 미정의 동작을 발생시킨다.&lt;ref name="C++03 5.6/4"&gt;ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages – C++ §5.6 Multiplicative operators [expr.mul] para. 4&lt;/ref&gt;
return x / 0; // undefined behavior
특정 포인터 연산은 미정의 동작을 초래할 수 있다.&lt;ref name="C++03 5.6/5"&gt;ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §5.7 Additive operators [expr.add] para. 5&lt;/ref&gt;
int arr[4] = {0, 1, 2, 3};
int* p = arr + 5; // undefined behavior for indexing out of bounds
p = nullptr;
int a = *p; // undefined behavior for dereferencing a null pointer
C 및 C++에서 객체에 대한 포인터의 관계 비교(보다 작음 또는 보다 큼 비교)는 포인터가 동일한 객체의 멤버 또는 동일한 배열의 요소를 가리키는 경우에만 엄격하게 정의된다.&lt;ref name="C++03 5.9/2"&gt;ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages – C++ §5.9 Relational operators [expr.rel] para. 2&lt;/ref&gt; 예시:
int b = 0;
return &amp;a &lt; &amp;b; // undefined behavior
반환 문 없이 값을 반환하는 함수(codice_18 제외)의 끝에 도달하면 호출자가 함수 호출의 값을 사용하는 경우 미정의 동작이 발생한다.&lt;ref name="C99 6.9.1/12"&gt;ISO/IEC (2007). ISO/IEC 9899:2007(E): Programming Languages – C §6.9 External definitions para. 1&lt;/ref&gt;
// undefined behavior if the value of the function call is used
두 sequence point 사이에서 객체를 두 번 이상 수정하면 미정의 동작이 발생한다. C++11부터 시퀀스 포인트와 관련하여 미정의 동작을 유발하는 원인에 상당한 변화가 있다. 최신 컴파일러는 동일한 객체에 대한 여러 순서 없는 수정이 발생할 때 경고를 내보낼 수 있다. 다음 예시는 C와 C++ 모두에서 미정의 동작을 유발한다.
// undefined behavior: two unsequenced modifications to i
return i++ + i++;
두 시퀀스 포인트 사이에서 객체를 수정할 때, 저장될 값을 결정하는 것 외의 다른 목적으로 객체 값을 읽는 것도 미정의 동작이다.&lt;ref name="C99 6.5/2"&gt;ISO/IEC (1999). ISO/IEC 9899:1999(E): Programming Languages – C §6.5 Expressions para. 2&lt;/ref&gt;
a[i] = i++; // undefined behavior
printf("%d %d\n", ++n, pow(2, n)); // also undefined behavior
C/C++에서 비트 시프트를 음수이거나 해당 값의 전체 비트 수보다 크거나 같은 비트 수로 수행하면 미정의 동작이 발생한다. 가장 안전한 방법(컴파일러 공급업체와 관계없이)은 항상 시프트할 비트 수(비트 연산자 codice_19 및 codice_20의 오른쪽 피연산자)를 다음 범위 내에 유지하는 것이다: [, ] (여기서 codice_21는 왼쪽 피연산자이다).
int num = -1;
unsigned int val = 1 « num; // shifting by a negative number - undefined behavior
num = 32; // or whatever number greater than 31
val = 1 « num; // the literal '1' is typed as a 32-bit integer - in this case shifting by more than 31 bits is undefined behavior
num = 64; // or whatever number greater than 63
unsigned long long val2 = 1ULL « num; // the literal '1ULL' is typed as a 64-bit integer - in this case shifting by more than 63 bits is undefined behavior
러스트의 예시.
안전한 러스트에서는 미정의 동작이 발생하지 않을 것으로 예상되지만, 부적절하고 안전하지 않은 코드는 여전히 사운드니스 홀로 알려진 미정의 동작을 안전한 코드에 노출할 수 있다.
예를 들어, 러스트의 많은 데이터 타입은 유용한 최적화를 가능하게 하는 불변성을 사용한다.
참조는 한 가지 예시인데, 근본적으로 원시 포인터와 동일한 표현을 가지고 있지만, 널, 정렬되지 않음, 또는 다른 방식으로 유효하지 않은 대상을 가리킬 수 없다. 따라서 이러한 불변성을 위반하는 것은 결과 참조가 어떻게 사용되든 관계없이 미정의이다.
use core::mem::zeroed;
/// Constructs a null reference.
pub const fn null_ref&lt;T: ?Sized&gt;() -&gt; &amp;T {
codice_22를 호출하는 것은 모든 참조 타입에 의해 부과되는 불변성 때문에 항상 잘못 형성되는데, 함수 자체가 codice_23 항목이 아니고 안전한 코드에서 호출될 수 있음에도 불구하고 그렇다.
또한, 어떤 널 포인터를 역참조하는 것도 미정의이지만, 많은 호스트 시스템은 여전히 세그멘테이션 오류에서 이러한 경우를 처리하도록 설계되어 있다.
use std::ptr::null;
let p: *const i32 = null();
// SAFETY: `p` is null and may not be dereferenced.
unsafe { *p };
컴퓨터 프로그래밍에서 미지정 동작(unspecified behavior)은 프로그래밍 언어의 여러 구현에 따라 달라질 수 있는 동작이다. 소스 코드가 다른 컴파일러에서 컴파일되거나, 동일한 컴파일러에서 다른 설정으로 컴파일될 때, 또는 동일한 실행 파일의 다른 부분에서 다른 동작을 보이는 컴퓨터 프로그램은 미지정 동작을 포함한다고 할 수 있다. 해당 언어 표준이나 사양은 가능한 동작 범위를 부과할 수 있지만, 정확한 동작은 구현에 따라 다르며 프로그램의 소스 코드를 검사하여 완전히 결정되지 않을 수 있다. 미지정 동작은 결과 프로그램의 외부 동작에서 종종 나타나지 않지만, 때로는 다른 출력이나 결과를 초래하여 잠재적으로 이식성 문제를 일으킬 수 있다.
컴파일러가 각 대상 플랫폼에 최적의 코드를 생성할 수 있도록, 프로그래밍 언어 표준은 주어진 소스 코드 구성에 대해 항상 특정 동작을 부과하지는 않는다. 모든 가능한 프로그램의 정확한 동작을 명시적으로 정의하지 않는 것은 언어 사양의 오류나 약점으로 간주되지 않으며, 그렇게 하는 것은 실현 불가능할 것이다. C 및 C++ 언어에서는 이러한 비-이식성 구성이 일반적으로 세 가지 범주로 분류된다: 구현 정의(implementation-defined), 미지정(unspecified), 그리고 미정의 동작(undefined behavior).
미지정 동작의 정확한 정의는 다양하다. C++에서는 "잘 구성된 프로그램 구성과 올바른 데이터에 대한 동작으로, 구현에 의존하는 것"으로 정의된다. C++ 표준은 가능한 동작의 범위가 일반적으로 제공된다고도 명시한다. 구현 정의 동작과 달리, 구현이 해당 동작을 문서화해야 하는 요건은 없다. 마찬가지로, C 표준은 "두 가지 이상의 가능성을 제공하고 어떠한 경우에도 어느 것이 선택될지에 대한 추가 요구 사항을 부과하지 않는" 동작으로 정의한다. 미지정 동작은 미정의 동작과 다르다. 후자는 일반적으로 잘못된 프로그램 구성 또는 데이터의 결과이며, 그러한 구성의 번역 또는 실행에 대한 요구 사항은 없다.
구현 정의 동작.
C와 C++는 구현 정의 동작과 미지정 동작을 구별한다. 구현 정의 동작의 경우, 구현은 특정 동작을 선택하고 이를 문서화해야 한다. C/C++에서 한 가지 예는 정수 데이터 유형의 크기이다. 동작 선택은 프로그램의 주어진 실행 내에서 문서화된 동작과 일치해야 한다.
하위 식 평가 순서.
많은 프로그래밍 언어는 완전한 식의 하위 식 평가 순서를 지정하지 않는다. 이러한 비결정성은 특정 플랫폼에 대한 최적의 구현을 허용할 수 있다(예: 병렬 처리 활용). 하나 이상의 하위 식이 부작용을 가질 경우, 전체 식을 평가한 결과는 하위 식의 평가 순서에 따라 달라질 수 있다. 예를 들어, codice_1에서 codice_2와 codice_3가 모두 codice_4를 수정하는 경우, codice_5 또는 codice_6 중 어느 것이 먼저 평가되는지에 따라 codice_7에 저장되는 결과가 달라질 수 있다. C 및 C++ 언어에서는 이것이 함수 인자에도 적용된다. 예시:
std::cout « "In f\n";
return 3;
int g() {
std::cout « "In g\n";
int sum(int i, int j) {
return i + j;
return sum(f(), g());
결과 프로그램은 두 줄의 출력을 미지정된 순서로 작성한다. 자바와 같은 일부 다른 언어에서는 피연산자와 함수 인자의 평가 순서가 명시적으로 정의된다.
Colorless green ideas sleep furiously는 노엄 촘스키가 1957년 저서 변형생성문법의 이론에서 문법적으로 잘 형성되었지만, 의미론적으로 무의미한 문장의 예시로 제시한 구절이다. 이 문장은 원래 그의 1955년 논문 《The Logical Structure of Linguistic Theory》와 1956년 논문 "Three Models for the Description of Language"에서 사용되었다. 이 문장에서는 명확하게 이해할 수 있는 의미를 도출할 수 없는데, 이는 통사론과 의미론의 구분을 보여주며, 통사론적으로 잘 형성된 문장이 의미론적으로도 잘 형성될 것이라는 보장은 없다는 점을 시사한다. 범주 오인의 한 예시로서, 이는 특정 확률적 문법 모델의 부적절함과 더 구조화된 모델의 필요성을 보여주기 위한 것이었다.
무의미하지만 문법적인.
촘스키는 1957년 저서 변형생성문법의 이론에 다음과 같이 썼다.
두 문장 (1)과 (2) 모두 이전에 영어 담화에서 등장한 적이 없었다고 가정하는 것이 합리적이다. 따라서 정문과 비문을 설명하는 모든 통계 모델에서 이 문장들은 영어에서 "동등하게 멀리 떨어진" 것으로 동일한 이유로 배제될 것이다. 그러나 (1)은 무의미하지만 문법적이며, (2)는 문법적이지 않다.
문장의 주어 역할을 하는 'Colorless green ideas'는 적어도 두 가지 이유에서 비정상적인 구절이다.
문장의 서술어 역할을 하는 'sleep furiously'는 구조적으로 잘 형성되어 있다. 즉, 문법적이다. 그러나 이 표현이 나타내는 의미는 특이한데, 잠을 자는 활동은 일반적으로 '맹렬하게' 할 수 있는 것으로 여겨지지 않기 때문이다. 그럼에도 불구하고 'sleep furiously'는 문법적이고 해석 가능하지만, 그 해석은 비정상적이다.
'Colorless green ideas'와 'sleep furiously'를 결합하면 일부 사람들은 무의미하다고 생각하는 문장이 된다. 한편으로는 'idea'와 같은 추상 명사는 잠을 자는 것과 같은 활동에 참여할 수 없다고 여겨진다. 다른 한편으로는 일부 사람들은 아이디어가 잠을 잘 수 있다고 생각한다.
언어학자들은 이 문장의 비정상적인 특성을 설명하기 위해 두 가지 유형의 선택을 구분한다. 즉, 의미 선택(s-선택)과 범주 선택(c-선택)이다. s-선택에 따르면 이 문장은 세 가지 이유로 의미론적으로 비정상적이다(무의미하다).
그러나 c-선택에 따르면 이 문장은 구조적으로 잘 형성되어 있다.
이는 이 문장이 의미는 없지만 구조적 완성도는 높다는 결론으로 이어진다.
의미 있는 해석 시도.
단어가 여러 의미를 갖는 다의어의 메커니즘을 사용하면 원래 무의미한 문장에 대한 해석을 만들 수 있다. 예를 들어, 형용사 'green'과 'colorless'는 모두 비유적인 의미를 가지고 있다. 'Green'은 "미숙한", "환경 의식과 관련된", "새로 형성된", "순진한" 등 다양한 비유적 의미를 가지고 있다. 그리고 'colorless'는 "특징 없는"으로 해석될 수 있다. 마찬가지로 동사 'sleep'은 "휴면 상태에 있다"는 비유적 의미를 가질 수 있으며, 부사 'furiously'는 "맹렬히 또는 빠르게 행동하다"는 비유적 의미를 가질 수 있다.
이러한 비유적 의미를 고려하면 "Colorless green ideas sleep furiously"라는 문장은 덜 모호한 의미를 가질 수 있으며, 따라서 다음과 같은 해석과 양립할 수 있다.
촘스키의 "colorless green"은 추가적인 맥락을 통해 의미론적으로 무의미한 발화에서 의미를 창조하려는 문학 작품에 영감을 주었다. 1958년, 언어학자이자 인류학자인 델 하임즈는 무의미한 단어가 올바른 순서로 배열될 때 의미 있는 것으로 발전할 수 있음을 보여주는 작업을 발표했다.
러시아계 미국인 언어학자이자 문학 이론가인 로만 야콥슨 (1959)은 "colorless green"을 옅은 초록색으로, "sleep furiously"를 "움직이지 않음, 무기력, 무감각과 같은 상태적인 잠"의 야성으로 해석했다. 야콥슨은 "만약 [누군가의] 증오가 결코 잠들지 않았다면, 어째서 누군가의 생각은 잠들지 않을 수 있겠는가?"라는 예를 들었다. 미국의 시인이자 문학 평론가인 존 홀랜더는 이 문장이 맥락이 없기 때문에 진공 상태에서 작동한다고 주장했다. 그는 이 아이디어를 바탕으로 한 시 "Coiled Alizarine"을 썼고, 이 시는 그의 저서 《The Night Mirror》(1971)에 실렸다.
몇 년 후, 홀랜더는 촘스키에게 'green'이라는 색상 선택이 의도적이었는지 물었지만, 촘스키는 어떤 의도나 영향도 부인했으며, 특히 앤드루 마벌의 "정원"(1681)에 나오는 구절의 가설적 영향도 부인했다.
문장에 맥락을 통해 의미를 부여하려 시도한 최초의 작가 중 한 명은 중국 언어학자 자오위안런 (1997)이다. 자오의 시 "Making Sense Out of Nonsense: The Story of My Friend Whose "Colorless Green Ideas Sleep Furiously" (after Noam Chomsky)"는 1971년에 출판되었다. 이 시는 "colorless green ideas"가 무엇이며 어떻게 "맹렬히 잠들 수 있는지" 설명하려 한다. 자오는 "colorless"를 평범한, "green"을 미숙한 것으로 해석하고, "sleep furiously"를 아이디어를 잠재우는 것으로 해석한다. 즉, 이 아이디어들과 내적 갈등을 겪으면서 밤새도록 잠을 자는 것이다.
영국 언어학자 앵거스 매킨토시는 촘스키의 발언이 전적으로 무의미하다는 것을 받아들일 수 없었다. 그에게는 "무색의 초록색 생각들이 맹렬히 잠들 수도 있기" 때문이다. 마치 그 문장들이 사실 의미가 있다는 것을 증명이라도 하듯, 매킨토시는 촘스키의 발언에 영향을 받아 두 편의 시를 썼는데, 그중 하나는 '악몽 I'이라는 제목이었다.
스탠퍼드 1985년 대회.
1985년 스탠퍼드 대학교에서 문학 대회가 열렸는데, 참가자들은 촘스키의 문장을 100단어 이내의 산문이나 14행 이내의 운문으로 의미 있게 만들라는 초대를 받았다.
C. M. Street의 대회 참가작 예시는 다음과 같다.
이것을 문자 대화에 적용하여 연구가 진행되었다. 예시바 대학교의 브루노 갈란투치(Bruno Galantucci)가 주도한 연구는 무의미한 문장을 실제 대화에 도입하여 반응을 시험했다. 그들은 30건의 대화를 진행했는데, 1명의 남성과 1명의 여성이 대화 중 침묵 시간에 "colorless green ideas sleep furiously"를 8분 동안 삽입했다. 대화가 끝난 후, 실험자들은 대화가 비정상적이었는지 주로 묻는 사후 설문조사를 실시했다. 갈란투치는 대화의 일관성에 대한 둔감성 경향이 있다고 결론지었다.
이 실험에서 도출된 두 가지 일반적인 이론이 있다. 첫 번째 이론은 사람들이 대화의 질을 보호하기 위해 발화의 불일치를 무시하는 경향이 있다는 것이다. 특히, 대면 대화는 온라인 메시징보다 무의미한 문장의 감지율이 33.33% 낮았다. 저자들은 또한 사람들이 모든 대화의 일부 내용을 종종 무시하는 방법을 설명한다. 저자들이 추론한 두 번째 이론은 대화의 일관성을 다룰 때 효과적인 의사소통이 무의식적으로 훼손될 수 있다는 것이다. 이러한 결론은 친교적 의사소통이 사회생활에서 핵심적인 역할을 한다는 아이디어를 지지한다.
통계적 난관.
2000년, 펜실베이니아 대학교의 페르난도 페레이라(Fernando Pereira)는 신문 텍스트 모음에 간단한 통계 마르코프 모델을 적용하여 이 모델에서 "Furiously sleep ideas green colorless"가 "Colorless green ideas sleep furiously"보다 약 20만 배 덜 확률적이라는 것을 보여주었다.
이 통계 모델은 유사성 측정 기준을 정의하며, 특정 측면에서 코퍼스 내의 문장과 더 유사한 문장에는 덜 유사한 문장보다 높은 값을 할당한다. 페레이라의 모델은 문법적으로 비문법적인 동일한 문장에 통사적으로 잘 형성된 구조보다 낮은 확률을 할당하여, 통계 모델이 최소한의 언어학적 가정을 가지고도 정문과 비문의 변형을 식별할 수 있음을 보여준다. 그러나 이 모델이 모든 비문법적인 문장에 모든 문법적인 문장보다 낮은 확률을 할당하는지는 명확하지 않다. 즉, 'colorless green ideas sleep furiously'는 일부 비문법적인 문장보다 통계적으로 영어에서 여전히 더 "멀리 떨어져" 있을 수 있다. 이에 대해, 현재의 어떤 문법 이론도 모든 문법적인 영어 문장을 비문법적인 문장과 구분할 수 없다고 주장할 수 있다.
관련 및 유사한 예시.
프랑스의 통사론자 뤼시앙 테니에르는 통사론과 의미의 대조를 보여주기 위해 다음 두 문장을 제시했다.
러시아 언어학파에서는 글로카야 쿠즈드라 예시가 유사한 특징을 가지고 있다.
우아한 시체 게임은 무의미한 문장을 생성하는 방법이다. 이 게임은 1925년 게임에서 생성된 첫 문장인 "Le cadavre exquis boira le vin nouveau"(우아한 시체가 새 포도주를 마실 것이다)에서 이름을 따왔다.
인기 게임 "매드 리브스"에서는 선택된 플레이어가 다른 플레이어에게 맥락 정보를 제공하지 않고 품사를 제공하도록 요청하며(예: "고유명사를 말해주세요" 또는 "형용사를 말해주세요"), 이 단어들은 올바른 문법 구조를 가지고 있지만 특정 단어가 생략된 미리 구성된 문장에 삽입된다. 이 게임의 유머는 문법적이지만 무의미하거나 터무니없거나 모호한 의미(예: '시끄러운 상어')를 가진 문장을 생성하는 데 있다. 이 게임은 또한 유머러스한 이중 의미를 생성하는 경향이 있다.
그러한 문장들의 더 이른 예시가 아마도 언어 철학 문헌에서 존재할 것이지만, 초점이 대부분 경계 사례에 맞춰져 있었기 때문에 반드시 논란의 여지가 없는 것은 아니다. 예를 들어, 논리실증주의 추종자들은 "형이상학적"(즉, 경험적으로 검증할 수 없는) 진술은 단순히 무의미하다고 주장한다. 예를 들어, 루돌프 카르나프는 마르틴 하이데거의 거의 모든 문장이 문법적으로 잘 형성되었지만 무의미하다고 주장하는 논문을 썼다.
철학자 버트런드 러셀은 1940년 저서 "의미와 진리에 대한 탐구"에서 "사중성(四重性)이 지연을 마신다(Quadruplicity drinks procrastination)"는 문장을 사용하여 유사한 주장을 펼쳤다. W.V. 콰인은 이에 대해 문장이 거짓이라는 것은 그것이 참이 아니라는 것일 뿐이며, 사중성은 아무것도 마시지 않으므로 그 문장은 단순히 거짓이지 무의미한 것이 아니라는 이유로 반대했다.
논쟁의 여지가 있지만 "무의미한" 다른 발화들은 의미가 있고 문법적이지만, 러셀의 "지칭에 관하여"에 나오는 "현재 프랑스 왕은 대머리이다"(프랑스에는 현재 왕이 없다)와 같이 세상의 현재 상태와는 아무런 관련이 없는 문장들이다. (또한 확정 기술구 참조).
문학 및 엔터테인먼트에서.
또 다른 접근 방식은 무의미한 단어를 사용하여 통사적으로 잘 형성되고 쉽게 파싱할 수 있는 문장을 만드는 것이다. 유명한 예시로는 "고스탁이 도쉬를 희미하게 한다(The gostak distims the doshes)"가 있다. 루이스 캐럴의 재버워키도 이 기술을 사용하는 것으로 유명하지만, 이 경우에는 문학적 목적을 위한 것이다. 신경과학 실험에서 사용되는 유사한 문장들을 재버워키 문장이라고 부른다.
언어학에 대한 스케치에서 영국 코미디 듀오 프라이 앤 로리는 "Hold the newsreader's nose squarely, waiter, or friendly milk will countermand my trousers." (뉴스 진행자의 코를 똑바로 잡으세요, 웨이터, 그렇지 않으면 친근한 우유가 내 바지에 대한 명령을 취소할 것입니다.)라는 무의미한 문장을 사용했다.
에피소드 "다르목"에서는 전적으로 민담과 이야기를 참조하여 소통하는 종족이 등장한다. 우주선의 범용 번역기는 이 이야기 속 인물과 장소를 올바르게 번역하지만, 의도된 의미를 해독하는 데 실패하여 피카드 선장은 외계인을 이해할 수 없게 된다.
실질 비함의(material nonimplication) 또는 절리(abjunction)는 일반 회로 및 불 논리에 사용되는 논리 연산을 나타내는 용어이다. 이는 실질 함축의 부정이다. 즉, 두 명제 formula_1와 formula_2에 대해 formula_1에서 formula_2로의 비함의는 formula_1에서 formula_2로의 실질 함축의 부정이 참인 경우에만 참이다. 이는 formula_1에서 formula_2로의 비함의가 참인 경우는 formula_1가 참이고 formula_2가 거짓인 경우뿐이라고 더 자연스럽게 말할 수 있다.
논리 표기법으로는 formula_11, formula_12 또는 "Lpq"(보첸스키 표기법)로 쓸 수 있으며, 논리적으로 formula_13 및 formula_14와 동치이다.
논리적 동치.
비함의는 실질 함축의 부정으로 정의될 수 있다.
고전 논리에서는 formula_15와 formula_2의 논리합의 부정과도 동치이며, formula_1와 formula_18의 논리곱과도 동치이다.
거짓 보존: 모든 변수에 "거짓"의 진릿값이 할당되는 해석은 비함의의 결과로 "거짓"의 진릿값을 산출한다.
비함의의 기호는 단순히 실질 함축 기호에 줄을 그은 것이다. 유니코드 기호는 219B16 (십진수 8603): ↛이다.
문법적.
"p 마이너스 q."
"p 빼기 q."
수사적.
"p 그러나 q는 아님."
"p에도 불구하고 q는 거짓이다."
비트 단위 연산: A &amp; ~B. 이는 보통 "비트 클리어"(BIC) 또는 "앤드 낫"(ANDN)이라고 부른다.
논리 연산: A &amp;&amp; !B.
논리학에서 진리 함수(truth function)는 진릿값을 입력으로 받아 고유한 진릿값을 출력하는 함수이다. 다시 말해, 진리 함수의 입력과 출력은 모두 진릿값이다. 진리 함수는 항상 정확히 하나의 진릿값을 출력하며, 동일한 진릿값(들)을 입력하면 항상 동일한 진릿값이 출력된다. 전형적인 예는 명제 논리에서 복합 명제가 논리 연산으로 연결된 개별 명제들을 사용하여 구성되는 경우이다. 만약 복합 명제의 진릿값이 구성 명제(들)의 진릿값에 의해 전적으로 결정된다면, 복합 명제는 진리 함수라고 불리며, 사용된 모든 논리 연산은 진리 함수적이라고 한다.
고전 명제 논리는 진리 함수적 논리이다. 이는 모든 명제가 참 또는 거짓 중 정확히 하나의 진릿값을 가지며, 모든 논리 연산이 진리 함수적(대응하는 진리표를 가짐)이므로 모든 복합 명제가 진리 함수이기 때문이다. 반면에 양상 논리는 비진리 함수적이다.
복합 문장의 진릿값이 하위 문장의 진릿값의 함수인 경우, 논리 연산은 진리 함수적이다. 논리 연산의 집합은 각 구성원이 진리 함수적일 경우 진리 함수적이다. 예를 들어, "그리고" 연산은 진리 함수적이다. 왜냐하면 "사과는 과일이고 당근은 채소이다"와 같은 문장은 "사과는 과일이다"와 "당근은 채소이다"라는 각 하위 문장이 참일 때만 참이고, 그렇지 않으면 거짓이기 때문이다. 영어와 같은 자연어의 일부 논리 연산은 진리 함수적이 아니다.
"x는 ...라고 믿는다" 형식의 논리 연산은 진리 함수적이 아닌 연산의 전형적인 예이다. 예를 들어 메리가 2000년 4월 20일에 앨 고어가 미국 대통령이었다고 잘못 믿지만, 달이 녹색 치즈로 만들어졌다고는 믿지 않는다고 가정하자. 그렇다면 다음 문장은
는 참이지만, 다음 문장은
는 거짓이다. 두 경우 모두, 각 구성 문장(즉, "앨 고어는 2000년 4월 20일에 미국 대통령이었다"와 "달은 녹색 치즈로 만들어졌다")은 거짓이지만, "메리는 ...라고 믿는다"라는 구를 접두사로 붙여 형성된 각 복합 문장은 진릿값이 다르다. 즉, "메리는 ...라고 믿는다" 형식의 문장의 진릿값은 구성 문장의 진릿값만으로는 결정되지 않으므로, (단항) 논리 연산 (또는 단항이므로 단순히 연산자)은 비진리 함수적이다.
공식 구성에 사용되는 고전 논리 연산(예: &amp;, →)은 진리 함수적이다. 인수로 다양한 진릿값을 사용할 때의 값은 일반적으로 진리표로 주어진다. 진리 함수적 명제 논리는 공식이 참 또는 거짓으로 해석될 수 있는 형식 체계이다.
이항 진리 함수 표.
2가 논리에서 두 입력 P와 Q에 대한 16가지 가능한 진리 함수가 있으며, 이를 불 함수라고도 한다. 이 함수들 각각은 고전 논리에서 특정 논리 연산의 진리표에 해당하며, 인수의 하나 또는 둘 모두에 의존하지 않는 함수와 같은 몇 가지 퇴화된 경우도 포함한다. 다음 진리표에서는 간결성을 위해 참은 1, 거짓은 0으로 표시한다.
함수적 완전성.
함수는 합성으로 표현될 수 있으므로, 진리 함수적 논리 계산은 함수적으로 완전하기 위해 위에 언급된 모든 함수에 대한 전용 기호를 가질 필요가 없다. 이는 명제 논리에서 특정 복합 명제의 논리적 동치로 표현된다. 예를 들어, 고전 논리에서 는 와 동치이다. 따라서 "¬"(부정)와 "∨"(논리합)가 이미 사용 중이라면 조건 연산자 "→"는 고전 기반 논리 체계에 필수적이지 않다.
명제 논리에서 표현 가능한 모든 명제를 표현할 수 있는 최소 연산자 집합을 최소 함수적 완전 집합이라고 한다. 최소 완전 집합의 연산자는 NAND만 {↑} 또는 NOR만 {↓}으로 달성된다.
아리티가 2를 초과하지 않는 최소 함수적 완전 연산자 집합은 다음과 같다.
대수적 속성.
일부 진리 함수는 해당 논리 연산을 포함하는 정리로 표현될 수 있는 속성을 가지고 있다. 이항 진리 함수(또는 해당 논리 연산)가 가질 수 있는 속성 중 일부는 다음과 같다.
진리 함수 집합은 다음 다섯 가지 속성 각각에 대해 이를 결여하는 구성원을 적어도 하나 포함할 때에만 함수적으로 완전하다.
항수.
구체적인 함수는 연산자로도 지칭될 수 있다. 2가 논리에는 2개의 널항 연산자(상수), 4개의 단항연산, 16개의 이항 연산자, 256개의 삼항 연산자, 그리고 formula_33개의 n항 연산자가 있다. 3가 논리에는 3개의 널항 연산자(상수), 27개의 단항연산, 19683개의 이항 연산자, 7625597484987개의 삼항 연산자, 그리고 formula_34개의 n항 연산자가 있다. k가 논리에는 k개의 널항 연산자, formula_35개의 단항 연산자, formula_36개의 이항 연산자, formula_37개의 삼항 연산자, 그리고 formula_38개의 n항 연산자가 있다. k가 논리의 n항 연산자는 formula_39 함수이다. 따라서 이러한 연산자의 수는 formula_40이며, 위의 숫자들이 여기서 유도되었다.
그러나 특정 항수를 가진 일부 연산자는 실제로 일부 입력에 대해 더 낮은 항수 연산을 수행하고 나머지 입력은 무시하는 퇴화된 형태이다. 위에 언급된 256개의 삼항 불 연산자 중 formula_41개는 포함배제의 원리를 사용하여 이항 또는 그 이하 항수 연산자의 퇴화된 형태이다. 삼항 연산자 formula_42는 실제로 하나의 입력에 적용되고 다른 두 입력은 무시하는 단항 연산자이다.
"부정"은 단항 연산자이며, 단일 항(¬P)을 취한다. 나머지는 이항 연산자이며, 두 항을 취하여 복합 명제()를 만든다.
논리 연산자 집합 는 다음과 같이 서로소 부분 집합으로 분할될 수 있다.
이 분할에서 formula_44는 항수 의 연산자 기호 집합이다.
더 익숙한 명제 논리에서는 formula_45가 일반적으로 다음과 같이 분할된다.
구성성 원리.
진리표를 사용하는 대신, 논리 연산 기호는 의미의 구성성 원리에 의해 상세히 설명된 바와 같이, 해석 함수와 함수적으로 완전한 진리 함수 집합(Gamut 1991)을 통해 해석될 수 있다.
를 해석 함수라 하고, 를 두 임의의 문장이라 하며, 진리 함수 fnand를 다음과 같이 정의하자.
그러면 편의를 위해 fnot, for, fand 등은 fnand를 통해 다음과 같이 정의된다.
또는 대안적으로 fnot, for, fand 등은 직접 다음과 같이 정의된다.
따라서 S가 논리 연산자를 나타내는 논리 기호 v1...vn과 비논리 기호 c1...cn으로 구성된 기호열인 문장이라고 하자. 그러면 이 fnand(또는 다른 함수적으로 완전한 진리 함수 집합)를 통해 v1부터 vn까지를 해석하도록 제공된 경우에만 의 진릿값은 c1...cn의 진릿값, 즉 에 의해 전적으로 결정된다. 다시 말해, 예상대로 S는 모든 비논리 기호의 해석 하에서만 참 또는 거짓이다.
위에 정의된 함수들을 사용하여, 명제의 진리 함수에 대한 형식적인 정의를 내릴 수 있다.
PROP를 모든 명제 변수의 집합이라고 하자.
진리 할당은 임의의 함수 formula_50로 정의한다. 진리 할당은 따라서 각 명제 변수를 특정 진릿값과 연결하는 것이다. 이는 명제의 진리표의 특정 행과 실질적으로 동일하다.
진리 할당 formula_51에 대해, 그 확장된 진리 할당 formula_52를 다음과 같이 정의한다. 이는 formula_51를 모든 명제 형식의 집합과 동일한 정의역을 갖는 새로운 함수 formula_54로 확장한다. formula_52의 치역은 여전히 formula_56이다.
마지막으로, 확장된 진리 할당을 정의했으므로, 이를 사용하여 명제의 진리 함수를 정의할 수 있다. 명제 A에 대한 진리 함수 formula_64는 모든 진리 할당의 집합과 동일한 정의역을 가지며, formula_56를 치역으로 가진다.
이는 각 진리 할당 formula_51에 대해 formula_67로 정의된다. formula_68에 의해 주어진 값은 formula_51로 식별된 행에 있는 A의 진리표의 마지막 열에 표시된 값과 동일하다.
논리 연산자는 디지털 회로에서 논리 회로로 구현된다. 거의 모든 디지털 회로(주요 예외는 DRAM)는 NAND, NOR, NOT, 그리고 전송 게이트로 구성된다. 일반적으로 2개 입력 대신 3개 이상의 입력을 가진 NAND 및 NOR 게이트는 상당히 일반적이지만, 논리적으로는 2개 입력 게이트의 캐스케이드와 동등하다. 다른 모든 연산자는 위의 2개 이상의 논리 게이트의 논리적으로 동등한 조합으로 분해하여 구현된다.
"NAND만", "NOR만", "NOT과 AND"의 "논리적 동등성"은 튜링 동치와 유사하다.
모든 진리 함수가 NOR만으로 표현될 수 있다는 사실은 아폴로 가이던스 컴퓨터에 의해 입증되었다.
성 마태오의 영감(The Inspiration of Saint Matthew, )은 이탈리아 바로크 대가 미켈란젤로 메리시 다 카라바조가 1602년에 그린 캔버스 유화이다. 프랑스 추기경 마티외 캥테렐의 의뢰로 제작된 이 그림은 로마의 프랑스 교단 산 루이지 데이 프란체시 성당의 콘타렐리 예배당 제단에 걸려 있다.
이 그림은 예배당에 있는 카라바조의 세 작품 중 하나로, 이전에 그려진 성 마태오의 순교와 성 마태오를 부르심 사이에 걸려 있다. 이것은 카라바조에게 쉬운 의뢰가 아니었으며, 세 그림 중 적어도 두 개는 후원자인 프란체스코 마리아 델 몬테 추기경가 만족하지 못해 교체되거나 다시 그려져야 했다.
1602년 2월, 예배당에 그의 첫 두 작품이 설치된 후 카라바조는 그 해 오순절까지 납품될 제단화를 제작하라는 의뢰를 받았다. 그가 처음 그린 그림인 성 마태오와 천사는 거부되었다. (이 작품은 제2차 세계 대전 중에 우연히 파괴되었다.)
그 후 이 작품은 비교적 빠르게 완성하였으며, 카라바조는 1602년 9월에 대금을 받았다.
천사는 공중에 떠 있는 숭고한 차원에 속하며, 물결치는 주름진 시트에 둘러싸여 있다. 불안해하는 마태오는 작업대에 몸을 기울이고, 천사는 그에게 앞으로 해야할 작업을 설명한다. 두 개의 큰 인물을 제외하고 모든 것이 어둠이다. 마태오는 서둘러 책상으로 달려온 듯하고, 그의 의자는 그림 공간 바깥으로 튀어나와 기울어져 있다. 마태오는 진지한 표정을 짓고 있다.
도메인 특화 모델링(domain-specific modeling, DSM)은 컴퓨터 소프트웨어와 같은 시스템을 설계하고 개발하는 소프트웨어 공학 방법론이다. 이 방법론은 도메인 특화 언어를 체계적으로 사용하여 시스템의 다양한 측면을 나타낸다.
도메인 특화 모델링 언어는 범용 모델링 언어보다 높은 수준의 추상화를 지원하는 경향이 있으므로, 주어진 시스템을 지정하는 데 더 적은 노력과 낮은 수준의 세부 정보가 필요하다.
도메인 특화 모델링은 종종 코드 생성의 개념, 즉 도메인 특화 언어 모델에서 실행 가능한 소스 코드 생성을 자동화하는 것을 포함한다. 소스 코드의 수동 생성 및 유지 관리로부터 자유로워진다는 것은 도메인 특화 언어가 개발자 생산성을 크게 향상시킬 수 있음을 의미한다. 수동 코딩에 비해 자동 생성의 신뢰성은 결과 프로그램의 결함 수를 줄여 품질을 향상시킬 것이다.
도메인 특화 언어는 1980년대의 CASE 도구나 1990년대의 UML 도구에서 시도된 이전의 코드 생성 시도와는 다르다. 이 두 가지 모두에서 코드 생성기와 모델링 언어는 도구 공급업체에 의해 구축되었다. 도구 공급업체가 도메인 특화 언어 및 생성기를 만들 수 있지만, 도메인 특화 언어가 하나의 조직 내에서 발생하는 것이 더 일반적이다. 한두 명의 전문 개발자가 모델링 언어와 생성기를 만들고, 나머지 개발자가 이를 사용한다.
모델링 언어와 생성기를 사용할 조직이 구축하면, 해당 도메인의 정확한 요구 사항에 밀접하게 부합하고 도메인 변경에 대응할 수 있다.