The Luhn algorithm is a simple checksum used to detect simple kinds of transcription errors, such as with credit card numbers. Here is how to do that kind of thing in Schematron. (Untested, it is just to indicate an approach in case anyone finds it useful.)
<sch:rule context="card-number">
<sch:let name="s" value="normalize-space(.)" />
<sch:let name="n" value="string-length( $s )" />
<sch:assert test=" $n = 11 ">
The card-number should have 11 digits.
</assert>
<sch:assert test=
"(number($s) + 2 * (
number(substring($s, $n - 1, 1)) +
number(substring($s, $n - 3, 1)) +
number(substring($s, $n - 5, 1)) +
number(substring($s, $n - 7, 1)) +
number(substring($s, $n - 9, 1)) )) mod 10 = 0">
The card-number should have a correct checksum,
using the Luhn algorithm.
</sch:assert>
<sch:rule>
(This example uses let variables, and so requires ISO Schematron or Schematron 1.6. If you are using Schematron 1.5, the change is only two lines of code to support let. But why use Schematron 1.5 which is about 8 years old now? ISO Schematron has many improvements.)

Print
Listen
By