Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wolfram mathematica 关于条件(/;)的问题_Wolfram Mathematica - Fatal编程技术网

Wolfram mathematica 关于条件(/;)的问题

Wolfram mathematica 关于条件(/;)的问题,wolfram-mathematica,Wolfram Mathematica,Condition具有属性HoldAll,该属性阻止在应用条件之前计算其第一个参数。但是由于某种原因,条件会计算其第一个参数,即使测试给出了False: In[1]:= Condition[Print[x],False] During evaluation of In[1]:= x Out[1]= Null/;False 为什么会这样?如果测试给出False,条件会评估其第一个参数,出于什么目的?在哪些情况下,此行为可能有用 p.S.条件用作设置延迟的第二个参数时,其行为不同: In[5]:=

Condition
具有属性
HoldAll
,该属性阻止在应用
条件之前计算其第一个参数。但是由于某种原因,
条件
会计算其第一个参数,即使测试给出了
False

In[1]:= Condition[Print[x],False]
During evaluation of In[1]:= x
Out[1]= Null/;False
为什么会这样?如果测试给出
False
,条件
会评估其第一个参数,出于什么目的?在哪些情况下,此行为可能有用

p.S.
条件
用作
设置延迟
的第二个参数时,其行为不同:

In[5]:= f:=Condition[Print[x],False]; f
Out[6]= f
In[31]:= RuleCondition[$ConditionHold[$ConditionHold[Print[3.`]]],True]
Out[31]= $ConditionHold[$ConditionHold[Print[3.]]] 

In[32]:= RuleCondition[$ConditionHold[$ConditionHold[Print[3.`]]],False]
Out[32]= Fail

这是我对所有案例的预期

条件
使用通常取决于左手边的内容,因此它必须至少在某种程度上评估LHS。考虑:

MatchQ[3, a_ /; IntegerQ[a]]
真的
p={a,b};
MatchQ[{3,0.2},p/;IntegerQ[a]&b<1]
真的 无论是从这个还是从这个角度,我都会猜到
Condition
具有属性
HoldRest
,而不是
HoldAll
。它可能需要
HoldAll
进行一些内部使用,可能与
SetDelayed
的用法有关。

据我所知(其他回答者已经提到了这一点),
Condition
不应被视为一个独立的函数,而应被视为一个用于形成涉及模式的更大表达式的包装器。但我想强调的是,这里的微妙之处部分来自这样一个事实:
Rule
RuleDelayed
都是范围界定结构。一般来说,作用域构造必须有一个变量绑定阶段,在该阶段,它们解决变量名称中可能存在的冲突,并实际将变量绑定到作用域构造体(或者,在
规则
规则延迟
的规则的r.h.s.)中出现的变量。这可能被认为是作用域结构内部工作的一部分,但是,由于Mathematica允许通过属性和
Evaluate
之类的东西进行顶级操作,作用域结构并不像看上去的那样是黑盒子-我们可以通过强制变量声明或主体,或两者来更改绑定,在绑定发生之前进行计算-例如,通过删除一些
Hold*
-属性。我更详细地讨论了这些事情,尽管我不知道作用域构造的确切实现细节,我不得不猜测

返回到
规则
规则延迟
条件
的情况,对
跟踪
所讨论的示例之一有指导意义:

In[28]:= Trace[Cases[{3,3.},a_:>Print[a]/;(Print["!"];IntegerQ[a])],RuleCondition,TraceAbove->All]
During evaluation of In[28]:= !
During evaluation of In[28]:= !
During evaluation of In[28]:= 3

Out[28]= {Cases[{3,3.},a_:>Print[a]/;(Print[!];IntegerQ[a])], 
{RuleCondition[$ConditionHold[$ConditionHold[Print[3]]],True],
      $ConditionHold[$ConditionHold[Print[3]]]},
{RuleCondition[$ConditionHold[$ConditionHold[Print[3.]]],False],Fail},
 {Print[3]},{Null}}
您看到的是,当
条件
规则
规则延迟
一起使用时,会出现特殊的内部标题
RuleCondition
。我的猜测是,这些实现了将模式变量的条件包括在内的机制,包括变量绑定。将
条件
用作独立函数时,不会显示这些条件。这些头对于条件机制的真正工作至关重要。 您可以查看它们在
规则
规则延迟
中的工作方式:

In[5]:= f:=Condition[Print[x],False]; f
Out[6]= f
In[31]:= RuleCondition[$ConditionHold[$ConditionHold[Print[3.`]]],True]
Out[31]= $ConditionHold[$ConditionHold[Print[3.]]] 

In[32]:= RuleCondition[$ConditionHold[$ConditionHold[Print[3.`]]],False]
Out[32]= Fail
您可以看到,例如,
案例
只拾取表单
$ConditionHold[$ConditionHold[something]]]
的元素,而忽略那些
规则条件
导致
失败的元素。现在,当您使用
条件
作为独立函数时,会发生什么情况?因此结果会有所不同

我知道的一个很好的例子,很好地说明了上述几点,是在中,其中讨论了使用
版本的可能实现,该版本按顺序绑定。我将在这里重复这一讨论的一部分,因为它很有启发性。我们的想法是制作一个版本的With,其中以前的声明可以用于声明列表的下一个声明。如果我们称之为
Let
,那么,例如

Clear[h, xl, yl];
xl = 1;
yl = 2;
h[x_, y_] := Let[{xl = x, yl = y + xl + 1}, xl^2 + yl^2];
h[a, b]
我们应该

a^2+(1+a+b)^2
其中一个建议的实施方案是:

ClearAll[Let];
SetAttributes[Let, HoldAll];
Let /: (lhs_ := Let[vars_, expr_ /; cond_]) := 
   Let[vars, lhs := expr /; cond]
Let[{}, expr_] := expr;
Let[{head_}, expr_] := With[{head}, expr]
Let[{head_, tail__}, expr_] := With[{head}, Let[{tail}, expr]]
(这是因为巴斯蒂安·埃尔德努斯)。这里发生的事情是,这个
Let
在运行时执行绑定,而不是在定义函数时执行绑定。一旦我们想要使用共享局部变量,它就会失败:

Clear[f];
f[x_,y_]:=Let[{xl=x,yl=y+xl+1},xl^2+yl^2/;(xl+yl<15)];
f[x_,y_]:=x+y;

?f
Global`f
f[x_,y_]:=x+y
如果您跟踪最后一次执行,就不清楚为什么
条件
没有在这里触发。原因是我们把装订阶段搞砸了。这是我的改进版,没有这些缺陷:

ClearAll[LetL];
SetAttributes[LetL, HoldAll];
LetL /: Verbatim[SetDelayed][lhs_, rhs : HoldPattern[LetL[{__}, _]]] :=
   Block[{With}, Attributes[With] = {HoldAll};
     lhs := Evaluate[rhs]];
LetL[{}, expr_] := expr;
LetL[{head_}, expr_] := With[{head}, expr];
LetL[{head_, tail__}, expr_] := 
  Block[{With}, Attributes[With] = {HoldAll};
    With[{head}, Evaluate[LetL[{tail}, expr]]]];
is所做的是在定义时而不是运行时将
LetL
扩展为嵌套的
,这发生在绑定阶段之前。现在,让我们看看:

In[122]:= 
Clear[ff];
ff[x_,y_]:=LetL[{xl=x,yl=y+xl+1},xl^2+yl^2/;(xl+yl<15)];

Trace[ff[3,4]]

Out[124]= {ff[3,4],       
{With[{xl$=3},With[{yl$=4+xl$+1},RuleCondition[$ConditionHold[$ConditionHold[xl$^2+yl$^2]],
 xl$+yl$<15]]],With[{yl$=4+3+1},RuleCondition[$ConditionHold[$ConditionHold[3^2+yl$^2]],3+yl$<15]],
{4+3+1,8},RuleCondition[$ConditionHold[$ConditionHold[3^2+8^2]],3+8<15],
{{3+8,11},11<15,True},RuleCondition[$ConditionHold[$ConditionHold[3^2+8^2]],True],
$ConditionHold[$ConditionHold[3^2+8^2]]},3^2+8^2,{3^2,9},{8^2,64},9+64,73}
您可以看到,
LetL
在定义时已扩展,如广告所示。由于模式变量绑定发生在这之后,所以一切正常。此外,如果我们添加另一个定义:

ff[x_,y_]:=x+y;

?ff
Global`ff
ff[x_,y_]:=With[{xl=x},With[{yl=y+xl+1},xl^2+yl^2/;xl+yl<15]]

ff[x_,y_]:=x+y
ff[x_u,y_u]:=x+y;
?ff
全球`ff

ff[x_u,y_u]:=With[{xl=x},With[{yl=y+xl+1},xl^2+yl^2/;xl+ylWith attribute
HoldRest
cases[{3,3},a:>Print[a]/;IntegerQ[a]]
@Alexey,是不是因为
规则延迟了
而不是
条件
的Hold属性而导致了
案例
的例子
呢?我认为“把戏”可能会落在对
/;
的特殊处理中:=
你所说明的
。@Mr Wizard你是对的。
取消保护[Condition];ClearAttributes[Condition,HoldAll];Cases[{3,3},a:>Print[a]/;IntegerQ[a]]
不会改变上述行为。似乎当
条件
置于
RuleDelayed
SetDelayed
的第二个参数内时,可能
TagSetDelayed
UpSetDelayed
的工作方式与默认情况下完全不同。有趣的是
RuleDelayed
它的工作原理不同
In[122]:= 
Clear[ff];
ff[x_,y_]:=LetL[{xl=x,yl=y+xl+1},xl^2+yl^2/;(xl+yl<15)];

Trace[ff[3,4]]

Out[124]= {ff[3,4],       
{With[{xl$=3},With[{yl$=4+xl$+1},RuleCondition[$ConditionHold[$ConditionHold[xl$^2+yl$^2]],
 xl$+yl$<15]]],With[{yl$=4+3+1},RuleCondition[$ConditionHold[$ConditionHold[3^2+yl$^2]],3+yl$<15]],
{4+3+1,8},RuleCondition[$ConditionHold[$ConditionHold[3^2+8^2]],3+8<15],
{{3+8,11},11<15,True},RuleCondition[$ConditionHold[$ConditionHold[3^2+8^2]],True],
$ConditionHold[$ConditionHold[3^2+8^2]]},3^2+8^2,{3^2,9},{8^2,64},9+64,73}
?ff
Global`ff
ff[x_,y_]:=With[{xl=x},With[{yl=y+xl+1},xl^2+yl^2/;xl+yl<15]]
ff[x_,y_]:=x+y;

?ff
Global`ff
ff[x_,y_]:=With[{xl=x},With[{yl=y+xl+1},xl^2+yl^2/;xl+yl<15]]

ff[x_,y_]:=x+y