From b754388da366827ad928b4c6075092c567a03a36 Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Wed, 30 Aug 2023 16:23:53 -0400 Subject: [PATCH] Estimate digits --- test/test_coverage.py | 5 +++++ test/test_turing.py | 14 +++++++------- tm/num.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/test/test_coverage.py b/test/test_coverage.py index 7c2c91b9..44e83b53 100644 --- a/test/test_coverage.py +++ b/test/test_coverage.py @@ -231,6 +231,11 @@ def test_num(self): ).run().marks print(marks) + assert not isinstance(marks, int) + print(marks.estimate()) + more_marks = marks * 3 // 2 + assert not isinstance(more_marks, int) + print(more_marks.estimate()) self.assertGreater(marks, 5) self.assertGreaterEqual(marks, 5) diff --git a/test/test_turing.py b/test/test_turing.py index a34eae3a..18f7c3ee 100644 --- a/test/test_turing.py +++ b/test/test_turing.py @@ -440,8 +440,6 @@ def _test_prover_est(self, prog_data: ProverEst): if not isinstance(result, int): print(f'--> {result}') - result = int(result) - if not isinstance(macro := self.machine.program, str): result *= macro.cells # type: ignore[attr-defined] @@ -452,16 +450,18 @@ def _test_prover_est(self, prog_data: ProverEst): if exp < 100_000: self.assert_close( - result / 10 ** exp, + int(result) / 10 ** exp, digits, rel_tol = .54, ) else: - assert isinstance(result, int) + magnitude = ( + int(log10(result)) + if isinstance(result, int) else + result.estimate() + ) - self.assertEqual( - exp, - int(log10(result))) + self.assertEqual(exp, magnitude) if result < 5: self.assert_could_blank(prog) diff --git a/tm/num.py b/tm/num.py index 0a628f1c..24097803 100644 --- a/tm/num.py +++ b/tm/num.py @@ -34,6 +34,25 @@ def __int__(self) -> int: int(self.r), ) + @abstractmethod + def estimate(self) -> int: ... + + def estimate_l(self) -> float: + return ( + l.estimate() + if isinstance(l := self.l, Num) else + 0 + if l < 1 else + log10(l) + ) + + def estimate_r(self) -> float: + return ( + log10(r) + if isinstance(r := self.r, int) else + r.estimate() + ) + @abstractmethod def __neg__(self) -> Count: ... @@ -126,6 +145,9 @@ class Add(Num): def __init__(self, l: Count, r: Num): super().__init__(l, r) + def estimate(self) -> int: + return round(max(self.estimate_l(), self.estimate_r())) + def __mod__(self, other: int) -> int: return ((self.l % other) + (self.r % other)) % other @@ -171,6 +193,9 @@ class Mul(Num): def __init__(self, l: Count, r: Num): super().__init__(l, r) + def estimate(self) -> int: + return round(self.estimate_l() + self.estimate_r()) + def __neg__(self) -> Count: return -(self.l) * self.r @@ -220,6 +245,9 @@ def __mod__(self, other: int) -> int: return ((self.l % other) * (inv % other)) % other + def estimate(self) -> int: + return round(self.estimate_l() - self.estimate_r()) + def __rmul__(self, other: Count) -> Count: if (isinstance(other, Num) or isinstance(self.r, Num) @@ -246,6 +274,9 @@ def __init__(self, l: Count, r: Count): super().__init__(l, r) + def estimate(self) -> int: + return round(self.estimate_l() * 10 ** self.estimate_r()) + def __neg__(self) -> Count: return ( Exp(-(self.l), self.r)