anchor.diff:  	(when (null (funcall (restricao-funcao-validacao r) p))
   	  (setf consistente nil)
   	  (return))))
  -    (psr-remove-atribuicao! p v1)
  -    (psr-remove-atribuicao! p v2)
  +
  +    (if atribuicao1 (psr-adiciona-atribuicao! p v1 atribuicao1) (psr-remove-atribuicao! p v1))
  +    (if atribuicao2 (psr-adiciona-atribuicao! p v2 atribuicao2) (psr-remove-atribuicao! p v2))
       (psr-altera-dominio! p v1 antigo-dominio1) ; TODO
       (psr-altera-dominio! p v2 antigo-dominio2) ; TODO
       (values consistente testes)))
  
positive.code: 	  (return-from procura-retrocesso-grau (values nil testes-total))))))
  
  
  ;;; procura-retrocesso-fc-mrv: PSR -> PSR, inteiro
  (defun procura-retrocesso-fc-mrv (p)
    ""
    (let ((testes-total 0))
      (if (psr-completo-p p)
  	(return-from procura-retrocesso-fc-mrv (values p testes-total))
  	(let* ((v (psr-mrv p))
  	       (d (psr-variavel-dominio p v)))
  	  (dolist (valor d)
  	    (multiple-value-bind (consistente testes) (psr-atribuicao-consistente-p p v valor)
  	      (incf testes-total testes)
  	      (when consistente
  		(psr-adiciona-atribuicao! p v valor)
  		(multiple-value-bind (inferencias inf-testes) (psr-forward-checking p v)
  		  (incf testes-total inf-testes)
  		  (when inferencias
  		    ; adiciona inferencias ao psr
  		    (multiple-value-bind (recurs-consistente recurs-testes)
  			(procura-retrocesso-fc-mrv p)
  		      (incf testes-total recurs-testes)
  		      (when recurs-consistente
  			(return-from procura-retrocesso-fc-mrv (values p testes-total))))
  		    ; remove infrerencias do psr
  		    ))
  		(psr-altera-dominio! p v d))))
  	  (return-from procura-retrocesso-fc-mrv (values nil testes-total))))))
  
  
  (defun psr-forward-checking (p v)
    ""
    (let ((testes-total 0)
  	(inferencias (make-hash-table :test 'equal))
  	(lista-arcos (arcos-vizinhos-nao-atribuidos p v)))
      (dolist (arco lista-arcos)
        (let ((v2 (first arco))
  	    (v1 (second arco)))
  	(multiple-value-bind (revise testes) (psr-revise p v2 v1 inferencias)
  	  (incf testes-total testes)
  	  (when revise
  	    (when (= (length (gethash v2 inferencias)) 0)
  	      (return-from psr-forward-checking (values nil testes-total)))))))
      (return-from psr-forward-checking (values inferencias testes-total))))
  
  
  (defun arcos-vizinhos-nao-atribuidos (p v)
    ""
    (let ((lista-arcos (list))) ; lista vs vector?
      (dolist (v-na (psr-variaveis-nao-atribuidas p))
        (when (not (equal v v-na))
  	(when (some #'(lambda (r) (find r (psr-variavel-restricoes p v-na)))
  		    (psr-variavel-restricoes p v))
  	  (push (cons v-na v) lista-arcos))))
      (nreverse lista-arcos)))
  
  
  (defun psr-revise (p x y inferencias)
    ""
    (let* ((testes-total 0)
  	 (revised nil)
  	 (dominio-x (gethash x inferencias (psr-variavel-dominio p x)))
  	 (novo-dominio-x dominio-x)
  	 (dominio-y (if (psr-variavel-atribuida-p p y)
  			(psr-variavel-dominio p y)
  			(gethash y inferencias (psr-variavel-dominio p y)))))
      (dolist (valor-x dominio-x)
        (when (dolist (valor-y dominio-y t)
  	      (multiple-value-bind (consistente testes)
  		  (psr-atribuicoes-consistentes-arco-p p x valor-x y valor-y)
  		(incf testes-total testes)
  		(when consistente (return nil))))
  	(setf revised t)
  	(setf novo-dominio-x (remove valor-x novo-dominio-x))))
      (when revised (push (gethash x inferencias) novo-dominio-x))
      (values revised testes-total)))
  
negative.code: (defun psr-atribuicao-consistente-p (p v valor)
    ""
    (let ((antigo-dominio (psr-variavel-dominio p v))
  	(atribuicao (psr-variavel-valor p v))
  	(consistente t)
  	(testes 0))
  
      (psr-altera-dominio! p v (list valor)) ; TODO: ainda e preciso?
      (psr-adiciona-atribuicao! p v valor)
      (setf (values consistente testes) (psr-variavel-consistente-p p v))
  
      (if atribuicao (psr-adiciona-atribuicao! p v atribuicao) (psr-remove-atribuicao! p v))
      (psr-altera-dominio! p v antigo-dominio) ; TODO: ainda e preceiso?
      (values consistente testes)))
  
  