Pergunta

É possível implementar amb-operador de McCarthy para escolha não-determinística em C #?

Aparentemente .NET carece de apoio de continuação, mas yield return poderia ser útil. Isso seria possível em outras .NET linguagens estáticas como F #?

Foi útil?

Solução

Sim, yield return faz uma forma de continuação. Embora para muitos casos úteis, Linq fornece operadores funcionais que permitem que você conecte juntos um gerador de seqüência preguiçoso, por isso, de fato, em C # 3, não é necessário usar yield return tanto (exceto ao adicionar mais extensões Linq de estilo de sua preferência para lacunas plugue na biblioteca, por exemplo, Zip, Unfold).

No exemplo que fatorar um número inteiro pela força bruta. Essencialmente o mesmo exemplo em C # pode ser feito com o built-in operadores 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);

Aqui, os pontos de partida são as minhas duas chamadas para Enumerable.Range, que é embutido para Linq, mas você pode implementar-se como:

IEnumerable<int> Range(int start, int stop)
{
    for (int n = start; n < stop; n++)
        yield return n;
}

Existem dois parâmetros ímpar, o n => 1, parâmetros n => 1 para Join. Eu estou escolhendo 1 como o valor da chave para Join para uso quando combinando-se itens, portanto, todas as combinações irá corresponder e assim que eu começar a testar todas as combinações de números das faixas.

Então eu ligar o par de valores em uma espécie de tupla (um tipo anônimo) com:

(i, j) => new { i, j })

Finalmente, eu pegar o primeiro tal tupla para a qual o meu teste está satisfeito:

.First(v => v.i*v.j == 481);

Atualizar

O código dentro da chamada para First não precisa ser meramente uma expressão de teste curto. Pode ser um monte de código imperativo que precisa ser "reiniciado" se o teste falhar:

.First(v => 
       {
           Console.WriteLine("Aren't lambdas powerful things?");

           return v.i*v.j == 481;
       );

Assim, a parte do programa que potencialmente precisa ser reiniciado com valores diferentes vai nesse lambda. Sempre que lambda quer reiniciar-se com valores diferentes, ele só retorna false -. O equivalente de chamar amb sem argumentos

Outras dicas

Esta não é uma resposta à sua pergunta, mas você pode obter o que deseja.

amb é usado para a computação não-determinístico. Como você deve saber, Prolog é uma linguagem não-determinístico usando a noção de unificação de valores se ligam a variáveis ??(basicamente o que amb acaba fazendo).

Não há uma implementação desta funcionalidade em C #, chamado YieldProlog. Como você adivinhou, o operador de rendimento é um requisito importante para isso.

http://yieldprolog.sourceforge.net/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top