2017-10-15 9 views

Répondre

2

What's the difference between #= and =:= in SWI prolog ?

La différence est que #=/2 est un opérateur de bibliothèque CLPFD (vous devez exécuter: use_module(library(clpfd)). afin de l'utiliser) et il est utilisé pour les contraintes arithmétiques et subsume à la fois is/2 et =:=/2sur int egers. Ce que cela signifie est que vous pouvez l'utiliser uniquement pour les entiers:

par exemple en utilisant la liste soulèvera erreur:

?- L #= [1,2,3]. 
ERROR: Domain error: `clpfd_expression' expected, found `[1,2,3]' 

(également d'utiliser des listes dans =:=/2 soulèvera erreur, l'exemple de liste est juste pour comprendre que les deux les opérateurs sont utilisés pour les expressions)

pour les entiers, il peut être utilisé partout =:= pourrait être utilisé, mais comme mentionné ci-dessus, il peut être utilisé comme is/2 ce qui signifie que vous pouvez l'utiliser pour l'unification - simplement lier une variable avec un entier valeur, par exemple:

?- X #= 2. 
X = 2. 

précède ne vérifie pas pour l'égalité entre les X et le numéro 2 depuis X dans la variable sans bornes, ce qu'il fait est la liaison X avec la valeur 2.

Ceci est impossible avec =:=/2 opérateur:

?- X =:= 2. 
ERROR: Arguments are not sufficiently instantiated 
ERROR: In: 
ERROR: [8] _2494=:=2 
ERROR: [7] <user> 

C'est parce que =:=/2 est utilisé uniquement pour vérifier l'égalité !! Il s'agit de la différence entre #=/2 et =:=/2. Les deux vérifient l'égalité entre deux expressions arithmétiques mais lorsque vous utilisez =:=/2toutes les variables doivent être instanciées. Lors de l'utilisation #=/2 avec des variables cela crée des contraintes entre ces variables:

?- X #= 2. 
X = 2.  % constraints X to integer value 2 

?- X + Y #= 2. 
X+Y#=2.  % constraints X,Y such that sum equals to 2 see next example: 

?- X + Y #= 2 , X = 3. 
X = 3, 
Y = -1.  % binds Y with -1 in order to succeed the constraint 

?- X + Y #= 2 , X = 3 , Y > 0. 
false.  % false since constraint can't succeed! 

Comme vous pouvez le voir #=/2 est nettement plus relationnelle car même en ayant une contrainte avec plus d'un exemple de variable X + Y #= 2. cela crée une relation entre X, Y, lier une variable peut conduire à un raisonnement de l'autre.

Dans vos tests, vous ne voyez aucune différence puisque toutes vos variables ont des valeurs (par exemple, elles sont instanciées) et vous vérifiez simplement l'égalité que les deux opérateurs peuvent atteindre.

1

Voir ce exemples:

:- use_module(library(clpfd)). 

solve_equation_1(X) :- X + 1 =:= 2. 
solve_equation_2(X) :- X + 1 #= 2. 
solve_equation_3(X,Y,Z) :- X + Y #= Z. 

Comme on pouvait s'y attendre, solve_equation_1 travaux pour X instancié et ne pas instancié comme =:= est un opérateur d'une simple vérification égalité des expressions:

?- solve_equation_1(1). 
true. 

?- solve_equation_1(2). 
false. 

?- solve_equation_1(X). 
=:=/2: Arguments are not sufficiently instantiated 

Cette ce n'est pas le cas pour #=. Il ne vérifie pas vraiment quoi que ce soit - il indique simplement que certaines variables et certains nombres sont limités de façon spécifique - par ex. ils forment une équation. Les vérifications et calculs réels ont lieu plus tard sauf si la contrainte/équation est si simple qu'elle peut être résolue immédiatement. C'est pourquoi, pour des cas très simples (comme vos exemples), #= peut ressembler à =:=.

Voir ces exemples - tous sont impossibles pour =:= et ils montrent ce résultat de #= n'est pas une valeur booléenne true/false mais de nouvelles contraintes:

?- solve_equation_2(X). 
X = 1. 

?- solve_equation_3(X,Y,2). 
X+Y#=2. 

?- X #= Y + Z, solve_equation_2(X). 
X = 1, 
Y+Z#=1