AMB-OPERATOR를 통한 비 결정적 선택
-
22-08-2019 - |
문제
구현할 수 있습니까? McCarthy 's amb
-운영자 C#에서 비 결정적 선택을 위해?
분명히 .NET는 계속 지원이 부족하지만 yield return
유용 할 수 있습니다. F#과 같은 다른 정적 .NET-Languages에서 가능합니까?
해결책
예, yield return
연속 형태를 수행합니다. 많은 유용한 경우에도 LINQ는 게으른 시퀀스 생성기를 연결할 수있는 기능 연산자를 제공하므로 실제로 C# 3에서는 사용할 필요가 없습니다. yield return
너무 많은 (라이브러리의 틈을 막기 위해 자신의 LINQ 스타일 확장을 더 추가 할 때 제외하고 ZIP, 전개).
예에서 우리는 잔인한 힘에 의해 정수를 고려합니다. 기본적으로 C#의 동일한 예는 내장 된 LINQ 연산자와 함께 수행 할 수 있습니다.
var factors = Enumerable.Range(2, 100)
.Join(Enumerable.Range(2, 100),
n => 1, n => 1, (i, j) => new { i, j })
.First(v => v.i*v.j == 481);
Console.WriteLine("Factors are " + factors.i + ", " + factors.j);
여기서 시작점은 나의 두 호출입니다 Enumerable.Range
, LINQ에 내장되어 있지만 다음과 같이 구현할 수 있습니다.
IEnumerable<int> Range(int start, int stop)
{
for (int n = start; n < stop; n++)
yield return n;
}
두 가지 홀수 매개 변수가 있습니다 n => 1
, n => 1
매개 변수 Join
. 나는 1을 핵심 가치로 선택하고 있습니다 Join
항목을 일치시킬 때 사용하려면 모든 조합이 일치하므로 범위에서 모든 숫자 조합을 테스트합니다.
그런 다음 값 쌍을 다음과 같은 종류의 튜플 (익명 유형)으로 바꿉니다.
(i, j) => new { i, j })
마지막으로 테스트가 만족하는 첫 번째 튜플을 선택합니다.
.First(v => v.i*v.j == 481);
업데이트
통화 내부의 코드 First
단지 짧은 테스트 표현 일 필요는 없습니다. 테스트가 실패하면 "다시 시작"해야하는 많은 명령 코드가 될 수 있습니다.
.First(v =>
{
Console.WriteLine("Aren't lambdas powerful things?");
return v.i*v.j == 481;
);
따라서 잠재적으로 다른 값으로 다시 시작 해야하는 프로그램의 일부는 해당 람다에 들어갑니다. Lambda가 다른 값으로 스스로를 다시 시작하기를 원할 때마다, 그것은 단지 거짓을 반환합니다 - amb
논쟁이 없습니다.
다른 팁
이것은 귀하의 질문에 대한 답이 아니지만 원하는 것을 얻을 수 있습니다.
AMB는 비 결정적 컴퓨팅에 사용됩니다. 아시다시피, Prolog는 통일 개념을 사용하여 변수에 값을 바인딩하기 위해 비 결정적 언어입니다 (기본적으로 AMB가 끝나는 일).
C#에서 수율 프로 로그라고하는이 기능의 구현이 있습니다. 당신이 추측 한 바와 같이, 수확량 운영자는 이것에 대한 중요한 필수 조건입니다.