Question

Est-il possible de mettre en œuvre amb-opérateur de McCarthy pour choix non-déterministe en C #?

Il semble que .NET manque de soutien de continuation mais yield return pourrait être utile. Serait-ce possible dans d'autres langues .NET statiques comme F #?

Était-ce utile?

La solution

Oui, yield return fait une forme de continuation. Bien que pour beaucoup de cas utiles, Linq fournit aux opérateurs fonctionnels qui vous permettent de brancher ensemble un générateur de séquence paresseux, donc en fait en C # 3 il est nécessaire d'utiliser yield return tant (sauf lors de l'ajout d'autres extensions de style Linq de votre propre à combler les lacunes dans la bibliothèque, par exemple Zip, déplier).

Dans l'exemple que nous factoriser un entier par la force brute. Essentiellement le même exemple en C # peut être fait avec les opérateurs LINQ intégré:

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);

Voici les points de départ sont mes deux appels à Enumerable.Range, qui est intégré à Linq mais vous pourriez vous mettre en œuvre comme:

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

Il y a deux paramètres impairs, le n => 1, les paramètres de n => 1 à Join. Je picking 1 comme valeur de clé pour Join à utiliser lors de l'appariement des éléments, d'où toutes les combinaisons correspondront et donc j'obtenir de tester toutes les combinaisons de nombres de plages.

Alors je retourne la paire de valeurs dans une sorte de tuple (un type anonyme) avec:

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

Enfin, je prends la première pour laquelle une telle ligne mon test est satisfaite:

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

Mise à jour

Le code dans l'appel à First ne doit pas être simplement une expression de test court. Il peut être beaucoup de code impératif qui doit être « redémarré » si le test échoue:

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

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

Ainsi, la partie du programme qui aura éventuellement besoin d'être redémarré avec des valeurs différentes va dans ce lambda. Chaque fois que lambda veut se remettre en marche avec des valeurs différentes, il retourne juste faux -. L'équivalent d'appeler amb sans argument

Autres conseils

Ce n'est pas une réponse à votre question, mais il peut vous obtenir ce que vous voulez.

amb est utilisé pour le calcul non déterministe. Comme vous le savez, Prolog est un langage non déterministe en utilisant la notion d'unification pour lier des valeurs aux variables (essentiellement ce que amb finit par faire).

Il y a une implémentation de cette fonctionnalité en C #, appelé YieldProlog. Comme vous l'aurez deviné, l'opérateur de rendement est une condition importante pour cela.

http://yieldprolog.sourceforge.net/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top