Haskell의 seq 연산과 호환되는 기능에 대한 eta-equivalence가 있습니까?


14

Lemma : 에타와 동등하다고 가정하면 (\x -> ⊥) = ⊥ :: A -> B.

증명 : ⊥ = (\x -> ⊥ x)에타 동등성 및 (\x -> ⊥ x) = (\x -> ⊥)람다 감소.

Haskell 2010 보고서, 섹션 6.2 seq는 두 가지 방정식으로 함수를 지정합니다 .

seq :: a-> b-> b
순차 ⊥ b = ⊥
a ≠ ⊥ 인 경우 seq ab = b

"결과적으로 ⊥는 \ x-> ⊥와 같지 않다. seq는 그것들을 구별하는데 사용될 수 있기 때문이다."

내 질문은, 이것이 실제로 정의의 결과 seq인가?

암묵적인 주장은 seqif이면 계산할 수없는 것 같습니다 seq (\x -> ⊥) b = ⊥. 그러나 나는 그런 seq것을 계산할 수 없다는 것을 증명할 수 없었습니다 . 나에게 그러한 것은 seq단조롭고 연속적이며 계산 가능한 영역에 그것을 넣습니다.

seq와 같은 구현 알고리즘은 ⊥ 로 시작 하는 도메인을 열거하여 어떤 x위치 를 검색하여 작동 할 수 있습니다 . 그러한 구현은 가능하더라도 다형성 을 만들고 싶을 때 꽤 털이 나옵니다.f x ≠ ⊥fseq

증거는 전혀 계산할 수 없다는 것을 거기에 seq그 식별 (\x -> ⊥)⊥ :: A -> B? 또한, 일부 건설이 seq식별 않는 (\x -> ⊥)로는 ⊥ :: A -> B?

답변:


6

먼저 λ xseq 와 구별 하는 방법에 대해 명시 적으로 설명하겠습니다 . :λx.

bottom :: a
bottom = bottom

eta :: a -> b
eta x = bottom

-- This terminates
fortytwo = seq eta 42

-- This does not terminate
infinity = seq bottom 42

따라서 Haskell λ x 에서 실험적인 사실입니다 . ⊥는 운영 체제는 구별된다. Haskell이 계산하기 때문에 계산할 수 있는 사실이기도 합니다. 하스켈에 대해 너무 많은. 하스켈 문서의 특정 문구에 대해 질문하고 있습니다. 나는 그 말을 읽어 두 주어진 방정식을 만족하기로되어 있지만, 그 두 방정식의 정의에 대한 충분하지됩니다 . 내가 당신에게 (단순히 입력)의 두 가지 모델을 제공 할 수 있습니다 : 여기 왜 λ -calculus하는 계산 가능하고 만족 주어진 방정식,하지만 모델 중 하나에 λ X . λx.seqseqseqλseqλx. 다른 한편으로는 동의하지 않지만 동의합니다.

연속 함수의 영역 에서 표현식이 해석 되는 간단한 도메인 이론적 모델에서 [ D E ] 우리는 = λ x 입니다. 분명히 . 효과적인 Scott 도메인 등을 가져 와서 모든 것을 계산 가능하게 만드십시오. 그러한 모델에서 쉽게 정의 할 수 있습니다.λ[DE]=λx.seq

λ x 를 구별 하는 calculus 모델을 가질 수도 있습니다 . 다음 물론 η - 규칙을 물을 수 없습니다. 예를 들어, 우리는 도메인의 기능을 해석하여이 작업을 수행 할 수 있습니다 [ D E ] , 즉, 별도의 바닥 함수 공간 도메인 연결. 이제 [ D E ] 의 맨 아래 이고 λ x 입니다. 는 바로 위에있는 요소입니다. 그들은 둘 다 평가하기 때문에 응용 프로그램으로 구별 할 수 없습니다λseqλx.η[DE][DE]λx. , 당신이 무엇을 적용하든 상관없이 (확장자는 동일합니다). 그러나 우리는도메인 간지도를 가지고 있으며 다른 모든 요소와 바닥을 구별합니다.seq


1
GHC 및 / 또는 포옹 ⊥ 및 λx에서 실험적인 사실입니다. 다행히 Haskell은 구현에 의해 정의되지 않습니다. 내 질문은 하스켈이 seq와 관련하여 지정되지 않았다는 것을 암시합니다.
Russell O'Connor

"효과적인 Scott 도메인"의 의미에 대한 참조를 줄 수 있습니까? 아마도 부분 순서가 결정 가능한 것은 아닙니다. 또한 STLC는 다형성이 아니지만 Haskell은 다형성입니다. 일반적으로 Haskell은 시스템 F 또는 그 파생어 중 하나로 해석됩니다. 이것이 당신의 주장에 어떤 영향을 미칩니 까?
Russell O'Connor

박사 학위 1.1.4 dissertation andrej.com/thesis/thesis.pdf 에는 효과적인 Scott 도메인에 대한 짧은 정의가 있으며 실제로 무료로 제공되는 첫 번째 Google 조회수입니다.
Andrej Bauer

2
나를 위해 증명을 작성하면 eta-rule이 (folder (\ ab-> fab) z xs)를 (folder fz xs)로 최적화하여 Haskell 98을 구현하면 O에서 점근 성능이 향상됩니다. (n ^ 2)에서 O (n)까지 ( ghc.haskell.org/trac/ghc/ticket/7436 참조 ) 더 강력하면 (NewTypeWrapper. f)의 NewTypeWrapper를 f를 확장하지 않고 최적화 할 수 있으며 GHC의 newType에 의해 현재 부과되는 일부 점근 적 성능 불이익을 방지 할 수 있습니다 (예 : 폴더 사용).
Russell O'Connor

1
실제로, 컴파일러는 항상 구현 해야합니다 . . 즉, 항상 λ x 와 같이 수축하지는 않을 수 있습니다 . 는 "때때로 구별 할 수있다"는 매우 위험한 상황이다. 이것이 사실이 아닌지 확인하려면 함수를 기본 요소에 적용하는 수많은 프로세스를 생성하는 영리한 방법으로 구현해야합니다 . 프로세스 중 하나라도 종료되면 계속 진행할 수 있습니다. 우리가 이것을 순차적으로 할 수 있는지 보는 것이 흥미로울 것입니다. 흠. λx.λx.seqseq
안드레이 바우어

2

seq인용 하는 사양 은 그 정의 가 아닙니다 . Haskell 보고서를 인용하려면 "seq 함수는 다음 방정식으로 정의됩니다 . [및 다음에 제공하는 방정식]".

seq (\ x-> ⊥) b = ⊥ 인 경우 seq를 계산할 수없는 것이 좋습니다.

이러한 동작은의 사양을 위반합니다 seq.

중요한 seq것은 다형성 이기 때문에 seq두 매개 변수 중 하나에서 해체 자 (투영 / 패턴 일치 등)로 정의 할 수 없습니다.

⊥ :: A-> B로 (\ x-> ⊥)를 식별하는 계산 가능한 seq가 없다는 증거가 있습니까?

인 경우 seq' (\x -> ⊥) b첫 번째 매개 변수 (함수)를 일부 값에 적용 한 다음 ⊥을 얻을 수 있다고 생각할 수 있습니다. 그러나 파라 메트릭 다형성 유형으로 인해 seq함수 값을 사용하여 첫 번째 매개 변수를 식별 할 수는 없습니다 (일부 사용하는 경우에도 마찬가지 임 seq). 매개 변수는 매개 변수에 대해 아무것도 모른다는 의미입니다. 또한, seq표현을 절대로 "이것이 ⊥입니까?"라고 결정할 수 없습니다. (참조, Halting 문제), seq단지 그것을 평가하려고 시도 할 수 있으며, 그 자체는 ⊥로 분기됩니다.

어떤 seq일은 다음, (아니 완전히하지만 최상위 생성자에 "약한 머리 정규형"[1], 즉에) 첫 번째 매개 변수를 평가하고 두 번째 매개 변수를 반환하는 것입니다. 첫 번째 매개 변수가 (즉, 비 종료 계산) 발생하면이 seq를 평가하면 종료되지 않습니다 seq ⊥ a = ⊥.

[1] seq가 존재하는 자유 정리-요한, 보이 그 랜더 http://www.iai.uni-bonn.de/~jv/p76-voigtlaender.pdf


seq에 제공하는 사양은 seq의 정의입니다. 이는 sek의 정의이므로 Haskell 2010 보고서에 섹션 6.2가 나와 있습니다. sek의 작업 정의는 Haskell 2010 보고서에서 지원되지 않습니다. "head normal form"이라는 단어는 완전히 다른 상황에서 보고서에서 한 번만 나타납니다. 또한 GHC가 첫 번째 인수 전에 두 번째 인수를 seq로 줄이거 나 엄격함 분석기가 정적이 아닌 것으로 입증 되었기 때문에 첫 번째 인수가 전혀 줄어들지 않는다는 나의 이해와 일치하지 않습니다.
Russell O'Connor

파라 메트릭은 해체자를 적용 할 수 없다고 말하거나 함수 값으로 첫 번째 매개 변수를 식별 할 수 없다고 말하지 않습니다. 모든 매개 변수는 고정 점이있는 다형성 람다 미적분학에 대해 seq는 엄격한 함수를 흡수하거나 더 일반적으로 항에 대한 특정 엄격한 관계가 seq를 포함한다고 말합니다. 나는 파라 메트릭 성이 (\ x-> ⊥) & ne; ⊥ 그러나 나는 엄격한 증거를보고 싶습니다.
Russell O'Connor

함수의 경우 f : forall a . a -> T( T다른 유형이있는 경우) f적용 할 해체자를 모르기 때문에 첫 번째 인수에 해체자를 적용 할 수 없습니다. 유형에 대해서는 "케이스"를 수행 할 수 없습니다. 위의 답변을 개선하려고 노력했습니다 ( seq정상적인 양식 을 평가하는 것에 대한 정보 인용 포함 ).
dorchard

나중에 시간을 찾으면 엄격한 증거를 시도 할 수 있습니다 (레이놀즈 스타일의 관계를 사용하는 것이 좋습니다).
dorchard

@ RussellO'Connor : seq에 대한 설명은 이러한 동작과 "일관되지 않음"이 아니라 작동 사양 일뿐입니다 (동작은 최종 결과를 변경하지 않는 최적화입니다).
Blaisorblade

2

λx.λx.

Samson Abramsky는 오래 전에이 문제를 고려하여 " The Lazy Lambda Calculus " 라는 논문을 썼습니다 . 따라서 공식적인 정의를 원한다면 여기가 보일 것입니다.


1
분명히, 이러한 세부 사항은 "Haskell 커널"로의 설탕을 제거함으로써 만 정의됩니다. 어디에 정의되어 있습니까? 보고서는 Sec. 1.2 : "커널은 공식적으로 지정되어 있지는 않지만 본질적으로 간단한 의미 론적 의미를 가진 람다 미적분의 약간 당화 된 변형입니다. 각 구문 구조를 커널로 변환하는 것은 구문이 도입 될 때 제공됩니다."
Blaisorblade

Haskell 2010 보고서는 놀라 울 정도로 동일 하다고 말합니다 .
Blaisorblade

Abramsky를 참조 해 주셔서 감사합니다! 나는 그것이 질문에 어떻게 대답하는지 알기 위해 그것을 감추었
Blaisorblade

2

λ x를 증명. Ω ‌ ≠ Ω in은 Abramsky가 게으른 람다 미적분학 이론 ( Uday Reddy가 이미 인용 한 논문의 2 페이지)에 대해 설정 한 목표 중 하나입니다 . 정의 2.7에서, 그는 에타 감소 λ x를 명시 적으로 논의한다. M x → M은 일반적으로 유효하지 않지만 모든 환경에서 M이 종료되면 가능합니다. 그렇다고해서 M이 전체 함수 여야한다는 의미는 아닙니다. M을 평가하는 것만 종료해야합니다 (예 : 람다로 축소).

귀하의 질문은 실제적인 관심사 (성능)에 의해 동기 부여 된 것으로 보입니다. 그러나 Haskell Report가 완전히 명확하지는 않지만 λ x와 같다는 의심이 듭니다. with ‌을 사용하면 Haskell을 유용하게 구현할 수 있습니다. Haskell '98을 구현했는지 여부는 논란의 여지가 있지만, 언급이 주어지면 저자가 그 사건을 의도 한 것은 분명합니다.

마지막으로 seq는 임의의 입력 유형에 대한 요소를 생성하는 방법은 무엇입니까? (QuickCheck가 임의 유형 클래스를 정의한다는 것을 알고 있지만 여기에 이러한 제약 조건을 추가 할 수는 없습니다). 이는 파라 메트릭을 위반합니다.

업데이트 : Haskel에 유창하지 않기 때문에이 권리를 코딩하지 못했습니다.이를 수정하면 중첩 된 runST영역 이 필요한 것 같습니다 . ST 참조에서 단일 참조 셀을 사용하여 이러한 임의의 요소를 저장하고 나중에 읽고 보편적으로 사용할 수 있도록했습니다. 매개 변수는 break_parametricity아래를 정의 할 수 없다는 것을 증명하지만 (예 : 오류를 반환하는 경우 제외) 제안 된 시퀀스가 ​​생성하는 요소를 복구 할 수 있습니다.

import Control.Monad.ST
import Data.STRef
import Data.Maybe

produce_maybe_a :: Maybe a
produce_maybe_a = runST $ do { cell <- newSTRef Nothing; (\x -> writeSTRef cell (Just x) >> return x) `seq` (readSTRef cell) }

break_parametricity :: a
break_parametricity = fromJust produce_maybe_a

필자는 여기에 필요한 파라 메트릭 증거를 공식화하는 데 약간의 애매함을 인정해야하지만, 비공식적 인 파라 메트릭 사용은 Haskell에서 표준입니다. 하지만 데릭 드레 이어의 저술에서 필요한 이론이 지난 몇 년 동안 빠르게 해결되고 있다는 것을 알게되었습니다.

수정 :

  • ML과 같은 명령형 및 유형이 지정되지 않은 언어로 연구되는 확장 기능이 필요한지 또는 고전적인 파라 메트릭 이론이 하스켈을 포함하는지 여부조차 확실하지 않습니다.
  • 또한 나는 데릭 드레 이어 (Dreek Dreyer)에 대해 언급했는데, 나중에 나중에 Uday Reddy의 작품을 만났기 때문에 "Reynolds의 본질"에서만 최근에 알게되었습니다. (나는 지난 달 정도에 파라 메트릭에 관한 문헌을 읽기 시작했습니다.)

(\x -> writeSTRef cell (Just x) >> return x)임의의 입력을 평가 해도 셀에 대한 쓰기는 실행되지 않습니다. 순서대로 전달 된 ST 명령 만 runST실행됩니다. 마찬가지로 running main = (putStrLn "Hello") `seq` (return ())은 디스플레이에 아무 것도 인쇄하지 않습니다.
Russell O'Connor

물론 @ RussellO'Connor는 여러분이 옳습니다. seq에 논의 된 동작이 없기 때문에 테스트가 어렵습니다. 그러나 여전히 요소 생성은 매개 변수 자체를 파괴한다고 생각합니다. 나는 그것을 예시하기 위해 답을 고치려고 노력할 것이다.
Blaisorblade

흠, 대답에 대한 명백한 수정은 runST 영역을 중첩하고 내부 영역의 외부 영역에서 셀을 사용해야하지만 허용되지 않습니다.
Blaisorblade
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.