^f(x) ::= x f(x) #### 0 - f(x) 1 - x f(x) 2 - x x f(x) 3 - x x x f(x) ... #### ^g(x) ::= x x #### g(f(x)) #### 0 - g(f(x)) 1 - f(x) f(x) 2 - x f(x) x f(x) 3 - x x f(x) x x f(x) ... #### my \$x = 3; my \$y = 3; if (3 == \$x) { # substitutability works print "\$x equals \$y.\n"; } \$x++; if (3 == \$y) { # substitutability fails print "\$x equals \$y.\n"; } #### my \$x = 3; # start frame of reference for variable \$x # start frame of reference for value \$x==3 my \$y = 3; # start frame of reference for variable \$y # start frame of reference for value \$y==3 if (3 == \$x) { print "\$x equals \$y.\n"; } # end frame of reference for value \$x==3 \$x++; # start frame of reference for value \$x==4 if (3 == \$y) { print "\$x equals \$y.\n"; } # end frame of reference for value \$x==4 # end frame of reference for variable \$x # end frame of reference for value \$y==3 # end frame of reference for variable \$y #### p1 ::= 'the morning star' equals 'the planet venus' p2 ::= 'the evening star' equals 'the planet venus' p3 ::= 'the morning star' equals 'the evening star' (+) ::= an operator that means 'two things which equal the same thing, equal each other' => ::= an operator which means 'this rule produces this result' #### p1 (+) p2 => p3 p1 (+) p3 => p2 p2 (+) p3 => p1 #### j1 ::= john knows 'the morning star' equals 'the planet venus' j2 ::= john knows 'the evening star' equals 'the planet venus' j3 ::= john knows 'the morning star' equals 'the evening star' #### j1 (+) p2 => j3 p1 (+) j2 => j3 j1 (+) p3 => j2 p1 (+) j3 => j2 j2 (+) p3 => j1 p2 (+) j3 => j1 #### sub outer_1 { local (\$x) = 1; return (inner (\$_)); } sub outer_2 { local (\$x) = 2; return (innner (\$_)); } sub inner { my \$y = shift; return (\$x + \$y); } #### sub equals { my (\$str, \$num) = @_; my %lut = ( 'one' => 1, 'two' => 2, 'three' => 3, ... ); if (\$num == \$lut{ \$str }) { return 1; } else { return 0; } } #### my \$inc = sub { return (\$_ + 1) }; my \$dec = sub { return (\$_ - 1) }; my \$zero = sub { return (0) }; sub apply { my (\$val, \$func, @etc) = @_; if (@etc) { return (\$val, apply (\$func->(\$val), @etc)); } else { return (\$val, \$func->(\$val)); } } sub counter { return apply (0, @_); } my @ops = ( \$inc, \$inc, \$inc, \$dec, \$inc, \$dec, \$dec, \$inc, \$zero, \$inc, \$inc, \$inc ); print join (' ', counter (@ops)); ---- output == '0 1 2 3 2 3 2 1 2 0 1 2 3' #### sub apply { my (\$val, \$func, @etc) = @_; if (@etc) { return (apply (\$func->(\$val), @etc)); } else { return (\$func->(\$val)); } } #### my @x = (\$inc, \$inc, \$inc); my @y = (\$inc, \$inc, \$inc); if (3 == counter (@x)) { printf "%d equals %d.\n", counter (@x), counter (@y); } do { my @x = (@x, \$inc); if (3 == counter (@y)) { printf "%d equals %d.\n", counter (@x), counter (@y); } }