불변이란 무엇입니까?


130

이 단어는 여러 맥락에서 사용되는 것 같습니다. 내가 생각할 수있는 최선의 것은 그것들이 변할 수없는 변수를 의미한다는 것입니다. 상수 / 최종 (Java!)이 무엇을위한 것이 아닌가?


아마도 그들은 그것을 비 변형이라고 불렀어야 했습니까?
조니

답변:


189

불변성은 변수보다 "개념적"입니다. 일반적으로 항상 참인 프로그램 상태의 속성입니다. 불변이 유지되도록하는 함수 또는 방법은 불변을 유지한다고합니다.

예를 들어, 이진 검색 트리는 모든 노드에 대해 노드의 왼쪽 자식 키가 노드의 자체 키보다 작다는 불변성을 가질 수 있습니다. 이 트리에 대해 올바르게 작성된 삽입 함수는 해당 불변을 유지합니다.

아시다시피, 그것은 변수에 저장할 수있는 종류가 아닙니다 . 프로그램 에 대한 설명 가깝습니다. 프로그램에서 유지해야하는 불변의 종류를 파악한 다음 코드를 검토하여 실제로 이러한 불변을 유지하는지 확인하면 코드의 논리적 오류를 피할 수 있습니다.


1
이 훌륭한 예는 wikipedia 링크에 cero의 답변을 포함하면 더 좋을 것입니다.
ablarg

2
부모의 나이는 생물학적 자녀의 나이보다 큽니다. 주변 상황은 변할 것이지만 불변성은 변하지 않습니다. 예를 들어, 2 명의 자녀를 둔 Smith 가족 일 수 있습니다. 또는 포유류의 다른 종에있을 수도 있습니다. 컨텍스트는 변경되지만 불변성은 변경되지 않습니다.
truthadjustr

1
"... 항상 참인 프로그램 상태의 속성 ..."-@jacob baskin-잘 작성되었으며 감사합니다.
twknab

"... 항상 사실 인 프로그램 상태의 속성 ..."-잘 작성되었다는 데 동의하지만 오해의 소지가 있습니다. 먼저 부울 사실로 이해했지만 "... 항상 일정 함"을 의미한다고 확신합니다 (하지만 영어가 제 모국어가 아니기 때문일 수도 있습니다)
dev-null

29

로직의 특정 위치에서 항상 참이라는 것을 알고있는 조건이며, 디버깅 할 때 문제를 해결하기 위해 확인할 수 있습니다.


17

일반적으로 알고리즘이나 구조 측면에서 더 많이 봅니다.

예를 들어, 각 반복의 시작 또는 끝에서 항상 참인 단언 할 수있는 루프 불변을 가질 수 있습니다. 즉, 루프가 한 스택에서 다른 스택으로 개체 모음을 처리해야하는 경우 루프의 맨 위 또는 맨 아래에 | stack1 | + | stack2 | = c라고 말할 수 있습니다.

불변 검사가 실패하면 문제가 발생한 것입니다. 이 예에서는 처리 된 요소를 최종 스택으로 푸시하는 것을 잊었 음을 의미 할 수 있습니다.


17

위키 백과의 마법 : 불변 (컴퓨터 과학)

컴퓨터 과학에서 참이면 특정 작업 순서 동안 참으로 유지되는 술어를 해당 순서에 대해 불변이라고합니다.


2
연결? 기술 용어? 독서? WTF ? ;) 진지하게, 좋은 링크이지만 약간의 요약이 좋을 것입니다.
Dustman

10

이 줄은 다음과 같이 말합니다.

컴퓨터 과학에서 참이면 특정 작업 순서 동안 참으로 유지되는 술어를 해당 순서에 대해 불변이라고합니다.

이 희망을 더 잘 이해하려면 C ++의이 예제가 도움이됩니다.

몇 가지 값을 가져와 as라는 변수에서 총 개수를 가져 와서 다음과 같은 변수에 count추가 해야하는 시나리오를 고려하십시오.sum

불변는 (다시 더 많은 개념처럼) :

// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades

위의 코드는 다음과 같습니다.

int count=0;
double sum=0,x=0;
while (cin >> x) {
++count;
sum+=x;
}

위의 코드는 무엇을합니까?

1)에서 입력을 읽고 cin넣습니다.x

2) 한 번 성공적으로 읽은 후 증가 countsum = sum + x

3) 읽기가 중지 될 때까지 1-2를 반복합니다 (예 : ctrl + D).

루프 불변 :

불변은 항상 True 여야합니다 . 그래서 처음에는 이것만으로 코드를 시작합니다.

while(cin>>x){
  }

이 루프는 표준 입력에서 데이터를 읽고 x에 저장합니다. 좋아요. 그러나 불변는 우리의 첫 번째 부분 때문에 거짓이 불변 다음 (또는 진정한 유지)하지 않았다.

// we have read count grades so far, and

불변성을 진실로 유지하는 방법?

단순한! 증가 수.

그래서 ++count;잘 할 것입니다!. 이제 우리 코드는 다음과 같이됩니다.

while(cin>>x){
 ++count; 
 }

그러나

지금도 우리의 불변 지금 우리의 두 번째 부분 만족하지 않았기 때문에 (TRUE 여야 개념) False입니다 우리의 불변을.

// sum is the sum of the first count grades

이제 어떻게해야합니까?

추가 x하고 ( )에 sum저장 하면 다음 번 에 새 값을 x로 읽습니다.sumsum+=xcin>>x

이제 우리 코드는 다음과 같이됩니다.

while(cin>>x){
 ++count; 
 sum+=x;
 }

점검 해보자

코드가 불변과 일치하는지 여부

// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades

암호:

while(cin>>x){
 ++count; 
 sum+=x;
 }

아!. 이제 루프 불변은 항상 True입니다. 이고 코드는 잘 작동합니다.

위의 예제는 Andrew-koening과 Barbara-E의 Accelerated C ++에서 가져와 수정되었습니다 .



2

그것이 무엇에 따라 불변는 불변이 존재해야하는지 개념적으로 알고 있기 때문에, 깨끗한 코드를 작성하기에 매우 유용 코드가 쉽게 그 목표에 도달하기 위해 코드를 구성하는 방법을 결정할 수 있습니다. 앞서 언급했듯이 불변이 유지되고 있는지 확인하는 것은 수행하려는 조작이 실제로 원하는 작업을 수행하는지 확인하는 좋은 방법이기 때문에 디버깅에도 유용합니다.


2

일반적으로 특정 수학 연산에서 변경되지 않는 수량입니다. 예를 들어 회전시 변경되지 않는 스칼라가 있습니다. 예를 들어 자기 공명 영상에서는 회전 불변으로 조직 속성을 특성화하는 것이 유용합니다. 왜냐하면 그 추정은 이상적으로 스캐너에서 신체의 방향에 의존하지 않기 때문입니다.


2

이 대답은 5 살짜리 아이를위한 것입니다. 불변을 상수 또는 고정 된 숫자 값으로 생각하지 마십시오. 하지만 그럴 수 있습니다. 그러나 그것은 그 이상입니다.

오히려 불변성은 다양한 엔티티 간의 고정 된 관계와 유사합니다. 예를 들어, 귀하의 나이는 항상 친부모에 비해 적습니다. 나이와 부모님의 나이는 시간이지나면서 변하지 만 위에서 언급 한 관계는 변하지 않습니다.

불변은 숫자 상수 일 수도 있습니다. 예를 들어의 값은 pi지름에 대한 원의 원주 사이의 불변 비율입니다. 원이 아무리 크든 작든 그 비율은 항상pi .


1

ADT 불변은 인스턴스 메서드 실행 전후에 항상 참이어야하는 데이터 필드 (인스턴스 변수) 간의 관계를 지정합니다.


0

불변의 훌륭한 예가 있으며 이것이 Java Concurrency in Practice 책에 중요한 이유가 있습니다 .

Java 중심이지만이 예제에서는 제공된 정수의 요소를 계산하는 일부 코드를 설명합니다. 예제 코드는 제공된 마지막 숫자와 성능 향상을 위해 계산 된 요소를 캐시하려고합니다. 이 시나리오에서는 동시 시나리오에서 경쟁 조건에 취약한 코드를 남겨둔 예제 코드에서 설명되지 않은 불변성이 있습니다.

여기에 이미지 설명 입력


0

여기에있는 모든 대답은 훌륭하지만 문제에 대해 더 많은 것을 밝힐 수 있다고 느꼈습니다.

언어 관점에서 불변은 결코 변하지 않는 것을 의미합니다. 개념은 실제로 수학에서 나왔지만 귀납법과 결합 할 때 인기있는 증명 기술 중 하나입니다.

다음은 증명이 진행되는 방식입니다. 초기 상태에있는 불변을 찾을 수 있고이 불변이 상태에 적용된 [법적] 변환에 관계없이 지속된다는 것을 증명할 수 있습니다. 불변하면 초기 상태에 어떤 변환 시퀀스가 ​​적용 되더라도 결코 발생할 수 없습니다.

이제 이전의 사고 방식 (다시 귀납법과 결합)은 컴퓨터 소프트웨어의 논리를 예측할 수있게합니다. 특정 루프가 특정 결과를 산출하거나 특정 방식으로 프로그램의 상태를 변경하지 않는다는 것을 증명하기 위해 불변을 사용할 수있는 루프에서 실행이 진행될 때 특히 중요합니다.

불변이 루프 논리를 술어하는 데 사용되는 경우 호출 된 루프 불변 입니다. 루프 외부에서 사용할 수 있지만 for 루프는 종종 많은 가능성 또는 무한한 가능성이 있기 때문에 정말 중요합니다.

내가 컴퓨터 소프트웨어의 논리를 "술어"라는 단어를 사용하고 증명하는 것이 아니라는 점에 유의하십시오. 그리고 그것은 수학에서 불변성 이 증명으로 사용될 수 있지만, 컴퓨터 소프트웨어가 실행될 때 예상되는 것을 산출 할 것이라는 것을 결코 증명할 수 없기 때문입니다. 소프트웨어가 많은 추상화 위에서 실행된다는 사실 때문에 결코 증명할 수 없습니다. 예상되는 것을 산출 할 것입니다 (예를 들어 하드웨어 추상화를 생각해보십시오).

마지막으로 소프트웨어 로직을 이론적으로 엄격하게 예측하는 것은 의료 및 군사용 애플리케이션과 같은 매우 중요한 애플리케이션에만 중요합니다. Invariant는 디버깅 할 때 일반적인 프로그래머를 지원하는 데 계속 사용할 수 있습니다. 특정 위치의 위치를 ​​아는 데 사용할 수 있습니다. 프로그램이 특정 불변성을 유지하지 못하여 실패했습니다. 우리 중 많은 사람들이 어쨌든 그것에 대해 생각하지 않고 그것을 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.