# recurrence equations for permutations:  perms(M) means  M!
"""{ defOK perms(0) == 1
     defOK perms(n) == perms(n-1) * n  }"""
#PREMISES FOR NEXT LINE: 

def fac(n) :
    """{ pre  n >= 0
         post  ans == perms(n)
         return ans  }"""
    #PREMISES FOR NEXT LINE: 
    # (n >= 0)
    if n == 0 :
        #PREMISES FOR THEN-ARM: 
        # (n == 0)
        # (n >= 0)
        ans = 1
        #PREMISES FOR ATTACHED PROOF, IF ANY: 
        # (ans == 1)
        # (n == 0)
        # (n >= 0)
        """{ 1.OK perms(0) == 1    def
             5.OK ans == 1         premise
             2.OK ans == perms(0)  algebra  1 5
             3.OK n == 0           premise
             4.OK ans == perms(n)  subst 3 2}"""
        #PREMISES FOR NEXT LINE: 
        # (ans == perms(n))
    else :
        #PREMISES FOR ELSE-ARM: 
        # not (n == 0)
        # (n >= 0)
        """{ 1.OK not(n == 0)   premise
             2.OK n >= 0        premise
             3.OK n - 1 >= 0    algebra 1 2
        }"""
        #PREMISES FOR NEXT LINE: 
        # ((n - 1) >= 0)
        # PRECONDITION VERIFIED FOR CALL:
        sub = fac(n-1)
        #PREMISES FOR ATTACHED PROOF, IF ANY: 
        # (sub == perms((n - 1)))
        # ((n - 1) >= 0)
        """{ 1.OK  sub == perms(n-1)    premise }"""
        #PREMISES FOR NEXT LINE: 
        # (sub == perms((n - 1)))
        ans = sub * n
        #PREMISES FOR ATTACHED PROOF, IF ANY: 
        # (ans == (sub * n))
        # (sub == perms((n - 1)))
        """{ 1.OK  ans == sub * n              premise
             2.OK  sub == perms(n-1)           premise
             3.OK  ans == perms(n-1) * n       subst 2 1
             4.OK  perms(n) == perms(n-1) * n   def
             5.OK  ans == perms(n)             algebra 4 3
        }"""
        #PREMISES FOR NEXT LINE: 
        # (ans == perms(n))
    #PREMISES FOR NEXT LINE: 
    # (ans == perms(n))
    # (n >= 0)
    """{ 1.OK  ans == perms(n)                 premise }"""
    #PREMISES FOR NEXT LINE: 
    # (ans == perms(n))
    # POSTCONDITION AND ALL GLOBAL INVARIANTS VERIFIED AT POINT OF RETURN
    return ans
    #PREMISES FOR NEXT LINE: 
    # (ans == perms(n))
    # POSTCONDITION AND ALL GLOBAL INVARIANTS VERIFIED AT END OF FUNCTION
#PREMISES FOR NEXT LINE: