2010-11-01 30 views

Répondre

2

Il y a plusieurs façons d'obtenir un tel effet, et que vous choisissez peut dépendre plus de détails de ce que vous avez l'intention de faire avec elle. Le plus simple est d'utiliser 2 arguments eval (ou subs, car l'évaluation devrait se produire en raison de la simplification automatique pour un produit impliquant 1 ou 0 exact).

> eval(5*true, [true=1,false=0]); 
          5 
> eval(x*false, [true=1,false=0]); 
          0 

Et bien sûr, vous pouvez créer une procédure pour gérer cette évaluation,

> T := expr -> eval(expr,[true=1,false=0]): 

> T(5*true); 
          5 
> T(x*false); 
          0 

Vous pouvez également essayer d'utiliser un module d'exportation (et redéfinir ainsi au « haut niveau » d'utilisation interactive) un * amélioré.

nb. Une version plus prudente de cette procédure exportée * ci-dessous ne remplacerait que «vrai» et «faux» si elle se produisait en tant que multiplicandes entiers, et ne ferait pas de remplacement dans l'ensemble de l'expression. (Une expression scalaire peut avoir des appels de fonctions non évaluées en elle, avec « vrais » et « faux » figurant dans, par exemple, les arguments facultatifs. Idéalement, ils devraient être laissés seuls.)

> M:=module() option package; export `*`; 
> `*`:=proc(ee::seq(anything)) 
>   :-`*`(op(eval([ee],[true=1,false=0]))); 
>  end proc; 
> end module: 

> with(M): 

> 5*true; 
          5 
> x*false; 
          0 

> a*b*c; 
         a b c 

> eval(%, b=false); # this doesn't play along 
         a false c 

Remarquez que la substitution de ' false 'dans ce dernier résultat n'a pas produit 0. C'est parce que le résultat de a * b * c (pour inconnus a, b, et c) est en termes de global: - * et non le nouveau *. Donc quand b = false est substitué, il n'y a pas d'appel au nouveau *. Il est possible de contourner cela aussi, bien que l'affichage qui en résulte est pas si belle (et le travail autour probablement « pauses » quelque chose que vous pourriez avoir l'intention de tout cela),

> M:=module() option package; export `*`; 
> `*`:=proc(ee::seq(anything)) 
>   local res; 
>   res:=:-`*`(op(eval([ee],[true=1,false=0]))); 
>   if type(res,:-`*`) then 
>   'procname'(op(res)); 
>   else 
>   res; 
>   end if; 
>  end proc; 
> end module: 

> with(M): 

> 5*true; 
          5 
> x*false; 
          0 

> a*b*c; 
        `*`(`*`(a, b), c) 

> eval(%, b=false); 
          0 

Dans ce dernier exemple ci-dessus , l'objet qui ressemble à * (* (a, b), c) est en fait en termes d'appels de fonctions non évalués au nouveau *. Donc quand b = false est substitué, il y a un appel au nouveau * et le résultat désiré peut être obtenu. (J'espère que cela ne mène pas à une récursion infinie dans un cas que j'ai oublié.)

2

Vous pouvez le faire avec:

subs([false=0, true=1], expr);