Skip to content

Latest commit

 

History

History
81 lines (55 loc) · 2.42 KB

eval.md

File metadata and controls

81 lines (55 loc) · 2.42 KB

Forward evaluation (add, multiply, exponentiate):

p :: 5 * 3 ~ c

mul_fun [5 3 c 5 3 15]  :: c ~ 15
  p                     :: 5 * 3 ~ c
  mul_def 5 3           :: 5 * 3 ~ 15

Backward evaluation (subtract, divide, logarithm, root):

p :: 5 * a = 15

mul_cancel_L [5 a 3]      :: a ~ 3
  leq_def 1 5             :: 1 <= 5
  eq_trans [5*a,15,5*3]   :: 5 * a ~ 5 * 3
    p                     :: 5 * a ~ 15
    eq_sym [5*3,15]       :: 15 ~ 5 * 3
      mul_def 5 3         :: 5 * 3 ~ 15

Chained forward evaluation:

p :: 5 + a ~ b
q :: 3 + b ~ c

Simplified equational form:

8 + a       ~
(3 + 5) + a ~
3 + (5 + a) ~
3 + b       ~
c

Full proof:

eq_trans [8+a,3+b,c]                :: 8 + a ~ c
  eq_trans [8+a,3+(5+a),3+b]        :: 8 + a ~ 3 + b
    eq_tarns [8+a,(3+5)+a,3+(5+a)]  :: 8 + a ~ 3 + (5 + a)
      add_cong [8,3+5,a,a]          :: 8 + a ~ (3 + 5) + a
        eq_sym [3+5,8]              :: 8 ~ 3 + 5
          add_def 3 5               :: 3 + 5 ~ 8
        eq_refl [a]                 :: a ~ a
      add_assoc [3,5,a]             :: (3 + 5) + a ~ 3 + (5 + a)
    add_cong [3,3,5+a,b]            :: 3 + (5 + a) ~ 3 + b
      eq_refl [3]                   :: 3 ~ 3
      p                             :: 5 + a ~ b
  q                                 :: 3 + b ~ c

We could avoid the nested eq_trans wiht a multi-arity variant, eqs:

eqs [8+a,(3+5)+a,3+(5+a),3+b,c] :: 8 + a ~ c
  add_cong [8,3+5,a,a]            :: 8 + a ~ (3 + 5) + a
    eq_sym [3+5,8]                  :: 8 ~ 3 + 5
      add_def 3 5                   :: 3 + 5 ~ 8
    eq_refl [a]                     :: a ~ a
  add_assoc [3,5,a]               :: (3 + 5) + a ~ 3 + (5 + a)
  add_cong [3,3,5+a,b]            :: 3 + (5 + a) ~ 3 + b
    eq_refl [3]                     :: 3 ~ 3
    p                               :: 5 + a ~ b
 q                                :: 3 + b ~ c

The idea is that:

eqs [a] []        = eq_refl [a]
eqs (a:as) (p:ps) = let q     = eqs as ps
                        b ~ c = proves q
                    in eq_trans [a,b,c] [p,q]

Note that the main benefit to using eqs is that it avoids some repeated instantiations: the seemingly more readable proof can be achieved by just pretty printing the original in a different way (eq_trans are the cons-nodes in the list of eqs).