^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 ($_[0])); } sub outer_2 { local ($x) = 2; return (innner ($_[0])); } 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 ($_[0] + 1) }; my $dec = sub { return ($_[0] - 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); } }