Pregunta

¿Es posible implementar amb-operador de McCarthy de elección no determinista en C #?

Aparentemente .NET carece de soporte continuación pero yield return podría ser útil. ¿Sería esto posible en otros idiomas NET-estáticos como F #?

¿Fue útil?

Solución

Sí, yield return hace una forma de continuación. Aunque para muchos casos útiles, LINQ proporciona a los operadores funcionales que le permiten conectar juntos un generador de secuencias perezoso, por lo que, de hecho, en C # 3 no es necesario el uso de yield return tanto (excepto cuando se añada más extensiones de estilo de LINQ de su propia para tapar agujeros en la biblioteca, por ejemplo, Zip, Despliegue).

En el ejemplo que factorizar un número entero por la fuerza bruta. Esencialmente el mismo ejemplo en C # se puede hacer con la incorporada en los 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);

A continuación, los puntos de partida son mis dos llamadas a Enumerable.Range, que está incorporada para LINQ pero se puede aplicar a sí mismo como:

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

Hay dos parámetros impares, el n => 1, parámetros n => 1 a Join. Estoy recogiendo 1 como el valor clave para Join a utilizar al hacer coincidir los elementos, por lo tanto, todas las combinaciones coincidirán y por lo que llegar a probar todas las combinaciones de números a partir de los rangos.

A continuación, se enciende el par de valores en una especie de tupla (un tipo anónimo) con:

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

Por último, tomo la primera tupla para el que mi prueba está satisfecho:

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

Actualizar

El código dentro de la llamada a First no tiene por qué ser una mera expresión de la prueba corta. Puede ser un montón de código imperativo que debe ser "reiniciado" si la prueba falla:

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

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

Así que la parte del programa que potencialmente se debe reiniciar con diferentes valores que va en lambda. Cada vez que quiere lambda reiniciará con diferentes valores, simplemente devuelve falso -. Equivale a llamar amb sin argumentos

Otros consejos

Esto no es una respuesta a su pregunta, pero puede conseguir lo que quiere.

amb se utiliza para la computación no determinista. Como ya sabrán, Prolog es un lenguaje no determinista usando la noción de la unificación de obligar a los valores de las variables (básicamente lo que termina haciendo amb).

Hay una implementación de esta funcionalidad en C #, llamado YieldProlog. Como has adivinado, el operador rendimiento es un requisito importante para esto.

http://yieldprolog.sourceforge.net/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top