具有非标准评估的自定义函数(表现得像表)

时间:2010-11-15 04:44:11

标签: wolfram-mathematica

我想要一个函数AnyTrue[expr,{i,{i1,i2,...}}]来检查expr True是否为i1,i2... AnyTrue Table Or@@% expr True Table后跟SetAttributes[AllTrue, HoldAll]; SetAttributes[AnyTrue, HoldAll]; AllTrue[{var_Symbol, lis_List}, expr_] := LengthWhile[lis, TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]] &] == Length[lis]; AnyTrue[{var_Symbol, lis_List}, expr_] := LengthWhile[lis, Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &] < Length[lis]; AllTrue[{a, {1, 3, 5}}, AnyTrue[{b, {2, 4, 5}}, EvenQ[a + b]]] AnyTrue[{a, {1, 3, 5}}, AllTrue[{b, {2, 4, 5}}, EvenQ[a + b]]] ,区别在于它只会在找到第一个{{1}}之前评估{{1}}。

短路部分是可选的,我真正想知道的是模拟{{1}}非标准评估序列的正确方法。

更新11/14

这是Michael的解决方案,您可以使用它来链接“for all”和“there exists”支票

{{1}}

2 个答案:

答案 0 :(得分:5)

这个怎么样?

SetAttributes[AnyTrue, HoldAll];

AnyTrue[expr_, {var_Symbol, lis_List}] :=
  LengthWhile[lis, 
    Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &
  ] < Length[lis]

通过LengthWhile包含短路,并在必要时保留所有内容,以便按预期工作,var的值超出函数范围:

In[161]:= x = 777;

In[162]:= AnyTrue[Print["x=", x]; x == 3, {x, {1, 2, 3, 4, 5}}]
During evaluation of In[162]:= x=1
During evaluation of In[162]:= x=2    
During evaluation of In[162]:= x=3
Out[162]= True

内置的Or也是短路的,因为它的价值。 (但我意识到用例如Table构建未评估的术语是一种痛苦):

In[173]:= Or[Print[1];True, Print[2];False]
During evaluation of In[173]:= 1
Out[173]= True

答案 1 :(得分:4)

这与您的规范不符,但我经常使用以下实用程序函数,它们与您的想法相似(它们使用纯函数而不是带有指定变量的表达式)并且还会进行短路:

some[f_, l_List] := True ===                (* Whether f applied to some      *)
  Scan[If[f[#], Return[True]]&, l];         (*  element of list is True.      *)

every[f_, l_List] := Null ===               (* Similarly, And @@ f/@l         *)
  Scan[If[!f[#], Return[False]]&, l];       (*  (but with lazy evaluation).   *)

例如,Michael Pilat的例子就是这样:

In[1]:= some[(Print["x=", #]; # == 3)&, {1, 2, 3, 4, 5}]

   During evaluation of In[1]:= x=1
   During evaluation of In[1]:= x=2    
   During evaluation of In[1]:= x=3
Out[1]= True