Comment comparer deux fonctions pour l'équivalence, comme dans (λx.2*x) == (λx.x+x)?
Est-il un moyen de comparer deux fonctions pour l'égalité? Par exemple, (λx.2*x) == (λx.x+x)
doit retourner true, car ceux sont évidemment équivalent.
- Avez-vous vraiment besoin de fonctions mathématiques ou êtes-vous simplement curieux au sujet de la comparaison des fonctions? Dans ce dernier cas, jetez un oeil à la normalisation dans tapé lambda calcul.
- juste par curiosité, mais je vais jeter un oeil sur elle.
- Votre conjonctif "mais" est de sortir de la place, il devrait plutôt être "tellement". 😉
- vous avez raison.
- connexes: stackoverflow.com/questions/13962811/...
- Si vous êtes intéressé dans le calcul de l'égalité (par exemple. pas dans les mathématiques de la théorie contexte) il y a seulement 4 milliards de flotteurs, de sorte que vous pouvez les tester tous les randomascii.wordpress.com/2014/01/27/...
- Cela sonne bien, jusqu'à ce que vous voulez prouver l'équivalence de deux fonctions binaires et tout à coup que 4 milliards de dollars taille du domaine est devenu 16 quintillion, et de votre essai de 1 minute suite est devenu un 10000 ans de suite de tests.
Vous devez vous connecter pour publier un commentaire.
Il est assez bien connu que la fonction générale de l'égalité est indécidable en général, de sorte que vous aurez à choisir un sous-ensemble de la problématique qui vous intéresse. Vous pourriez envisager de certaines de ces solutions partielles:
prove $ \(x::SInt32) -> 2*x .== x + x
résultats dansQ.E.D.
C'est indécidable en général, mais d'un sous-ensemble, en effet, vous pouvez le faire aujourd'hui efficacement à l'aide de solveurs SMT:
Pour plus de détails, voir: https://hackage.haskell.org/package/sbv
En outre des exemples concrets donnés dans l'autre réponse, laissez-nous chercher le sous-ensemble de fonctions exprimable dans tapé lambda calcul, nous pouvons également nous laisser le produit et la somme des types. Bien que de vérifier si deux fonctions sont égales peut être aussi simple que en les appliquant à une variable et de comparer les résultats, nous ne pouvons pas construire l'égalité de la fonction dans le langage de programmation lui-même.
ETA: λProlog est une logique de langage de programmation pour manipuler (tapé lambda calcul) de fonctions.
(\x -> 2*x) == (\x -> x*2)
?2 ans ont passé, mais je voudrais ajouter un petit mot à cette question. A l'origine, je lui ai demandé si il n'y a aucun moyen de dire si
(λx.2*x)
est égal à(λx.x+x)
. L'Addition et la multiplication sur le λ-calcul peut être définie comme:Maintenant, si vous normaliser les termes suivants:
Vous bénéficiez de:
Pour les deux programmes. Depuis leurs formes normales sont égales, les deux programmes sont évidemment égaux. Bien que cela ne fonctionne pas, en général, il fonctionne pour le nombre de termes dans la pratique.
(λx.(mul 2 (mul 3 x))
et(λx.(mul 6 x))
les deux ont les mêmes formes normales, par exemple.Dans un langage de calcul symbolique comme Mathematica:
Ou C# avec un algèbre informatique de la bibliothèque:
Ci-dessus affiche "True" dans la console.
(x \[Function] x + x) == (y \[Function] 2 y)
est un support, il n'essayez même pas.Prouvant deux fonctions de l'égalité est indécidable en général, mais on peut encore prouver fonctionnelle de l'égalité dans des cas particuliers comme à votre question.
Voici un exemple de preuve dans le Lean
On peut faire la même chose dans d'autres dépendante tapé langue comme le Coq, Agda, Idris.
Ci-dessus est une tactique de style de la preuve. La définition même de
foo
(la preuve), qui est généré est tout à fait une bouchée à être écrit à la main: