wolfram-mathematica
평가 주문
수색…
비고
이것은 가능한 한 명백하게 평가 순서를 설명하기로되어있다. 아마 Mathematica 실행에 대한 소개로 이상적이지는 않습니다. Mathematica의 tutorial/Evaluation 페이지는 다양한 규칙이 적용되는 순서를 설명하고 평가 엔진이 특별히 다루는 함수를 설명함으로써 구성됩니다.
평가 컨텍스트
어느 시점에서든 코드는 컨텍스트 내에서 실행됩니다. 컨텍스트는 대체 규칙 집합 (사전)과 평가되어야 할 우선 순위로 구성됩니다. 우리는 다섯 가지 종류의 문맥을 별개의 동작 및 제한으로 그룹화합니다. * 컨텍스트 설정 * 블록 컨텍스트 * 일치 컨텍스트 * ReplaceAll 컨텍스트 * ReplaceRepeated 컨텍스트
컨텍스트 설정
설정 컨텍스트는 Set [] 작업의 일부 집합 (더 일반적으로 작성된 함수 = )에 의해 정의 된 컨텍스트입니다. 주된 예는 주 실행 환경입니다. 그 사전은 다른 경우가 아닌 변수에 대해 Set []이 실행될 때마다 수정됩니다. 컨텍스트 설정의 다른 인스턴스는 패키지에서 발생합니다. 패키지 컨텍스트는 부모 컨텍스트와 관련이 있습니다. 이는 패키지 내의 모든 패턴도 해당 접두어가있는 부모 컨텍스트 내의 패턴이됩니다 (정의 foo[x_]=3*x 는 InnerPackageName\ foo [x _] = 3 * x가됩니다. `).
집합 컨텍스트에는 머리글과 연관된 문자열 인 "태그"와 연관된 규칙 만 포함 할 수 있으므로 규칙의 적용 가능성을보다 빨리 식별 할 수 있습니다. Set[yyy_,zzz_] 의 응용 프로그램은 yyy 가 기호인지 확인하여 태그를 결정합니다. 그럴 경우 태그입니다. 그렇지 않으면 yyy[[0]] , yyy[[0,0]] 등을 확인합니다. 어떤 시점에서 이것이 심볼로 결정된다면 그것은 태그로 간주됩니다. 대신 기호가 아닌 원자 (예 : String, Integer, Real ...) 인 경우 오류가 발생하고 규칙이 작성되지 않습니다.
함수 UpSet (쓰여진 ^= )과 TagSet (쓰여진 /: / = ) (및 그들의 사촌 UpSetDelayed와 TagSetDelayed)는 규칙을 다른 태그와 연관시킬 수 있습니다. 태그가 반드시 심볼이어야한다는 여전히 제한이 있습니다. UpSet은 표현식의 각 인수 또는 머리 부분에 대한 기호가있는 함수 인 경우 해당 머리와 연관시킵니다. 예를 들어,에 화가 호출 f[a,b,c+d,e[f,g],5,h[i][j][k],p_] 함께 생성 규칙을 연결한다 , a b , e , 및 h . c+d , 5 및 p_ 인수는 관련이 없으므로 오류 메시지가 표시됩니다. 할당은 각 인수에 대해 계속 성공하며 (평가 순서의 뒷부분에서 명확 해짐) 거의 모든 목적으로 계속 작동합니다. TagSet은 UpSet과 비슷하지만 태그에 정확히 하나의 심볼을 지정할 수 있습니다. 기호는 여전히 Set 또는 UpSet (머리글 또는 인수의 최상위 기호)로 설정할 수 있어야합니다. 예를 들어, TagSet[f, f[a,b[c]], 2] 는 허용 가능하며 정의를 f 와 연관시킵니다. TagSet[a, f[a,b[c]], 2] 와 TagSet[b, f[a,b[c]], 2] TagSet[c, f[a,b[c]], 2] 아닙니다.
컨텍스트 내부의 규칙은 주어진 표현식에 적용되는 규칙이 많기 때문에 애플리케이션 우선 순위가 필요합니다. ReplaceAll 및 ReplaceRepeated Contexts에서도 마찬가지지만 처리 방식은 매우 다릅니다. 우선 순위는 일반적으로 패턴의 특수성 과 일치하도록 설계됩니다. 머리와 인자가 모두 완전히 평가 된 상태에서 평가할 수있는 표현식 a[q][b[c,d],e[f,g]] 가 주어지면 태그가 붙은 규칙 적용되는 b 와 함께; 그런 다음 규칙은 e 태그가 지정됩니다. 다음에 a 태그가 붙은 규칙. 각 규칙 집합 내에서 주어진 심볼과 관련된 순서가 유지됩니다. 공백이없는 규칙 (예 : f[a,b]=3 )은 자동으로 맨 위에 배치되고 표준 순서 (정렬 순서)로 정렬됩니다. 새 규칙이 추가 될 때마다 커널은 목록을 검토합니다. 어떤 규칙이 똑같은 LHS를 가지고 있다면, 그 자리에서 대체된다. 그렇지 않으면 특이성 비교를 수행합니다. 목록에 이미있는 규칙 X가 새 규칙 Y보다 "덜 구체적인"것으로 결정되면 Y는 X 바로 앞에 위치합니다. 그렇지 않으면 목록을 통해 계속됩니다. 덜 구체적 인 규칙이 없으면 규칙은 목록의 끝에 배치됩니다. 특이성 검사는보다 복잡하며 아래 절에서 자세히 설명합니다.
규칙의 특이성
*이 표현은 BlankSequence (의 어떤 인스턴스가없는 경우 __ ), BlankNullSequence ( ___ ), 옵션 ( : ), 대안 ( | ) 반복, ( .. ), RepeatedNull ( ... ), 또는 선택적 인수를 ( _. ), 다음 그들은 구조적으로 비교 될 수 있습니다. Y에있는 모든 공백이 X에서도 공백이지만 X에 공백이있는 두 개의 동등한 표현식 트리 X와 Y가있는 경우 Y가보다 구체적입니다. * 두 표현 중 어떤 경우 것을 제외하면 동일하다 _ 치환 된 __ 다른 식 또는 __ withh 대체되었다 ___ , 그 이전보다 구체적이다. (제거 한 번 더 선택하는 경우 * : ) (또는 옵션 _. ) 용어는 다른 표현을 제공하고 후자는보다 구체적이다. * 대안의 특정 선택 집합이 다른 표현을 제공하면 후자는 더 구체적입니다. 의 모든 인스턴스를 교체 할 경우 * RepeatedNull[foo] 에 Repeated[foo] , 또는 Repeated[foo] 와 foo , 후자는이 규칙의 일부 combations이 한 번에 적용 할 수 있습니다 * 더 구체적이고 다음 다른 표현을 제공하지만, 현재이 아니다 이것에 대한 사례가 무엇인지 알아라. * _List 와 {___} 같은 식의 결합은 이론적으로는 동일하게 취급해야하지만, 비교는 상황에 따라 이상하게 해석되는 경우가 종종 있습니다.
컨텍스트 차단
블록 컨텍스트는 블록 내 규칙의 LHS가 기호 일 수 있다는 점에서보다 제한적입니다. 즉, f[x_]=2+x 아닌 f[x_]=2+x f=2+x 형식의 정의 만 있습니다. 실용적인 관점에서 볼 때 함수는`Set [블록은 부모 컨텍스트와 관련이있다. 블록의 평가 중에 새로운 정의가 둘러싸인 컨텍스트로 정상적으로 전달된다는 점에서 여전히 블록과 관련이 있지만, 주변의 문맥의 정의를 숨길 수있는 정의를 제공하는 일부 변수 집합을 "그림자"하게합니다. 내부 문법의 평가 중에는 주변 문맥의 정의에 계속 액세스 할 수 있습니다. 기호와 연관된 정의 만있을 수 있기 때문에 개념이 없습니다 위의 우선 순위.
일치하는 컨텍스트
규칙이 일치하면 변수에 로컬로 바인딩 된 정의가 있습니다. 이것은 어휘 적으로 발생합니다. 즉, 표현식의 변수에 대한 바운드 정의에서 다른 것을 평가하지 않고 다시 정의됩니다. 모든 하위 분할이 발생했을 때만 전체적으로 상위에서 다시 표현을 평가하기 시작합니다. 일치 컨텍스트가 작성되는 기본 방법은 컨텍스트 또는 규칙 설정의 규칙입니다. 예를 들어,
g[a_]:=a+x;
f[x_]:=x+g[1];
f[x^2]
(*Yields 1+x+x^2 *)
f[x_] 규칙을 f[y] 와 일치 시키면 기호 x 는 값 x^2 바인딩됩니다. 하나의 치환을 수행하지만 g 평가하지 않기 때문에 x^2+g[1] 반환합니다. 이것은 주변의 Set Context에서 다시 평가되고 1+x+x^2 됩니다. 일치 된 컨텍스트에서 중요한 차이점은 대체가 재귀가 아니라는 점 입니다. 그것이 x->x^2 나눌 때, 그것은 그 자신의 결과조차도 반복하지 않는다.
일치 된 컨텍스트는 With , Module , Function 및 Replace 작성됩니다. 다른 많은 함수는 내부적으로 함수를 생성합니다. 예를 들어 Plot 은 표현할 표현식을 평가할 때 이러한 유형의 컨텍스트를 사용합니다.
ReplaceRepeated Context 바꾸기
의 모든 응용 프로그램 때 ReplaceRepeated 컨텍스트가 생성됩니다 ReplaceRepeated 발생합니다. 이는 _[_] 와 같이 태그가없는 LHS를 포함하여 규칙 LHS로 표현식을 가질 수 있다는 점에서 뚜렷합니다. 이러한 의미에서 가장 유연한 컨텍스트입니다. 또한 충돌 할 수있는 몇 가지 규칙을 포함 할 수 있으므로 우선 순위를 유지해야합니다. ReplaceRepeated Context는 적용 가능한 경우 목록의 첫 번째 규칙을 먼저 적용합니다. 일치하지 않으면 두 번째 등으로 진행합니다. 어느 시점에서든 규칙이 일치하면 첫 번째 규칙으로 돌아가 다시 시작됩니다. 언제든지 규칙 적용이 발생하고 변경이 발생하지 않으면 목록의 다른 규칙이 나중에 변경 되더라도 종료됩니다. 즉, 목록의 앞부분에 덜 구체적인 규칙이 있으면 나중에 규칙을 사용하지 못하게됩니다. 또한 a_->a 규칙 목록 앞에 놓으면 ReplaceRepeated 전체가 즉시 종료됩니다.
ReplaceAll Context
의 모든 응용 프로그램 때 완전히 대체 컨텍스트가 생성됩니다 ReplaceAll 발생합니다. 그것의 기능은 ReplaceRepeated의 기능과 비슷합니다. 규칙 적용 우선 순위는 목록에서 두 가지가 모두 같은 수준의 표현식에 적용될 수있는 순서로 진행됩니다. 그러나, 그것은 대체 된 내용이 나중에 규칙에 의해서조차도 더 이상 평가되지 않는다는 점에서 Matched Context와 같습니다. 예를 들어, x/.{x->y,y->z} y 산출합니다. 따라서 ReplaceAll의 응용 프로그램이 각 규칙을 차례대로 적용하는 것을 보는 것은 올바르지 않습니다. 대신 적용되는 규칙을 찾아 트리를 탐색합니다. 일치하는 것을 찾으면 교체를 실행 한 다음 새 트리를 탐색하지 않고 트리를 리턴합니다. 또한 규칙을 위에서 아래로 적용하려고 시도 할 가능성이 있으며 결과적으로 목록의 순서가 어긋날 수도 있습니다. 예를 들어,
Cos[1 + 2 Sqrt[Sin[x]]] /. {Cos[_] -> 5, Sin[_] :> (Print[1]; 10)}
Cos[1 + 2 Sqrt[Sin[x]]] /. {Sin[_] :> (Print[1]; 10), Cos[_] -> 5}
둘 다 아무것도 인쇄하지 않고도 5 를 산출합니다. Cos[_] 가 트리의 상위 레벨과 일치하기 때문에 Cos[_] 가 먼저 적용됩니다.
Hold 및 Evaluate 및 실행 순서
* Head가 Hold 속성 ( HoldFirst , HoldRest , HoldAll , HoldAllComplete )을 가지고 HoldAll , * 관련 인수를 확인하십시오. HoldAllComplete 아니면 머리가 Evaluate 인지 확인하십시오. 그렇다면 Evaluate 를 제거하고 Evaluate 하도록 마크하십시오. * 인스턴스의 인수 확인 Unevaluated 하고 재산하지 않는 한, 필요에 스트립 HoldAllComplete 존재합니다. *에서 인수 평평 Sequence 하지 않는 한,들 SequenceHold 적용됩니다. * 적용 가능한 경우 Flat , Listable , Orderless 특성을 적용하십시오. * 인수의 upvalues (해당 태그)와 관련된 평가를 적용 * 머리와 관련된 평가를 적용합니다.
표현식의 평가가 완료되면 완전히 평가 된 것으로 표시됩니다. 그 표현식에 영향을 미치는 후속 평가는 평가하지 않습니다. 새로운 규칙이 내부에서 발생하는 기호에 정의되어 있으면 플래그가 제거되고 다시 평가할 수 있습니다. 이 '실패'하는 주목할만한 장소는 Condition ( \; )입니다 : 조건부 규칙은 초기 평가에 적용되지 않을 수 있습니다. 관련이없는 기호가 값을 변경하고 조건이 적용 가능하면 식은 완전히 평가 된 것으로 표시되고 결과로 변경되지 않습니다. Update 함수는 이미 평가 된 상태와 관계없이 인수를 평가하여 정렬의 "캐시 플러시"를 강요한다는 점에서 고유합니다.
Hold , Defer , ReplacePart , Extract 또는 ReleaseHold 와 같이 예외적 인 것으로 간주되는 많은 다른 기능이 있습니다. 이러한 효과는 속성 (예 : HoldAll ) 및 일반 함수 정의를 통해 모두 달성 할 수 있으며 평가자가 고유하게 처리 할 필요가 없습니다.
`ReplaceAll`과`ReplaceRepeated`의 적용
ReplaceAll 은 한 번만 규칙을 적용하는 방법에 대한 예제이며 ReplaceRepeated 는 루프에서 수행하지만 항상 첫 번째 규칙에서 응용 프로그램을 다시 시작합니다.
x + a /. {
a_ + z :> (Print[0]; DoneA),
a_ + x :> (Print[1]; y + z),
a_ + y :> (Print[2]; DoneB)}
(* Prints "1", yields "y+z" *)
x + a //. {
a_ + z :> (Print[0]; DoneA),
a_ + x :> (Print[1]; y + z),
a_ + y :> (Print[2]; DoneB)}
(* Prints "1", then prints "0", yields "DoneA" *)
버블 정렬
규칙 및 교체를 사용한 버블 정렬 :
list = {1, 4, 2, 3, 6, 7, 8, 0, 1, 2, 5, 4}
list //. {fsts___, x_, y_, lsts___} :> {fsts, y, x, lsts} /; y < x
(*
Out[1] := {1, 4, 2, 3, 6, 7, 8, 0, 1, 2, 5, 4}
Out[1] := {0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8}
*)