It should be possible to detect termination when an argument is smaller than a dotted pattern. For instance, the following code should terminate:
module Test where data Nat : Set where zero : Nat suc : Nat -> Nat data Bool : Set where true : Bool false : Bool _&&_ : Bool -> Bool -> Bool true && b = b false && b = false data Ty : {_ : Nat} -> Set where Base : forall {n} -> Ty {suc n} Arr : forall {n} -> Ty {n} -> Ty {n} -> Ty {suc n} subty : forall {n} -> Ty {n} -> Ty {n} -> Bool subty Base Base = true subty (Arr σ τ) (Arr σ' τ') = subty σ' σ && subty τ τ' subty _ _ = false
Currently the termination checker cannot see that in both the two recursive calls of subty
the first (hidden) argument is strictly smaller than on the LHS.
Andreas: Discussed that with Ulf. The internal syntax erases the dotted patterns constructed during pattern checking. This is an optimization for speeding up execution, but the "logical" reading (fully reconstruced form) of the second clause is
subty {suc n} (Arr {n} σ τ) (Arr {n} σ' τ') = subty {n} σ' σ && subty {n} τ τ'
To keep internally a fully reconstructed form is probably not only useful for the termination checker but also for other static analyses.
To print back the fully reconstructed form, as for instance Twelf does, is also a good feedback to the user: He sees how the system "understood" his input, and he can check that it understood it correctly. See Main.PrintReconstructedTerms feature request.