Liskov substitutability does not mean that you can substitute an object of a subclass for an object of a superclass and your program will still be correct. The only thing it guarantees is that promises made by the superclass will be honored by all subclasses.
In your case, the superclass promised "My speed will not exceed 100", and it keeps that promise. The subclass also keeps this promise.
The subclass also introduces a new, stricter promise: "My speed will not exceed 50", and it honors this promise as well. This is possible because the states allowed by the new premise are a strict subset of the states allowed by the old promise.
The superclass doesn't honor this new promise, in fact it doesn't even know about it. That means that its behaviour will be different from the behaviour of the subclass. Obviously, this can affect program correctness - substitutability does not mean that any of the classes in a class hierarchy is as good as the other.
Then what good is Liskov substitutability? It's only as good as the type system in your language. It does a good job enforcing pre- and postconditions that the type system in your language can express. For instance, once you declare a method that returns an unsigned int
, you can be sure that it will never return a negative value, and neither will any subclass. But you probably cannot express "this method finds the best nearest-neighbour classification of the input values" in the type system, therefore the LSP cannot guarantee program correctness under inheritance. (To be fair, almost no formalism can.)