(set-defunc-function-contract-strictp nil) (set-defunc-body-contracts-strictp nil) (definec sum (n :nat) :nat (if (equal n 0) 0 (+ n (sum (- n 1))))) (time$ (sum (expt 10 3))) (time$ (sum (expt 10 4))) (time$ (sum (expt 10 5))) (time$ (sum (expt 10 7))) ;; Hmm. What is going on? We need a tail recursive definition. (definec asum (n :nat acc :nat) :nat (if (equal n 0) acc (asum (- n 1) (+ n acc)))) (definec tsum (n :nat) :nat (asum n 0)) (time$ (sum (expt 10 3))) (time$ (tsum (expt 10 3))) (time$ (sum (expt 10 5))) (time$ (tsum (expt 10 5))) ; this one led to a stack overflow before (time$ (tsum (expt 10 7))) (time$ (tsum (expt 10 8))) (time$ (tsum (expt 10 9))) "So, notice we went from about about 0.05 to 0.5 to 5 seconds, an exponential increase in time by increasing the size of the input by 1 (we added one 0)." (expt 10 7) ; 1 followed by 7 0s (expt 10 8) ; size increased by 1 (expt 10 9) ; size increased by 1 "Let's see how our efficient definition does." (definec fsum (n :nat) :nat (/ (* n (+ n 1)) 2)) "Let's ask ACL2s to prove it is equivalent to the previous definition." (thm (implies (natp n) (equal (sum n) (fsum n)))) "This took tsum ~ 5 seconds" (time$ (fsum (expt 10 9))) "The next form would take tsum ~5*10^3=5000 seconds ~1.3 hours to do" (time$ (fsum (expt 10 12))) "The next form would take tsum ~5*10^11 seconds ~15,000 years to do" (time$ (fsum (expt 10 20)))