Я пытаюсь написать доказательство того, что 2^n * 2^m = 2^(n+m)
в Идрисе. Прямо сейчас у меня есть это:
expLaw : (power 2 n) * (power 2 m) = power 2 (n + m)
expLaw {n=Z} {m} = plusZeroRightNeutral (power 2 m)
expLaw {n=S n'} {m=m'} =
trans (multAssociative 2 (power 2 n') (power 2 m')) $
cong {f=mult 2} $ expLaw {n=n'} {m=m'}
Это дает мне ошибку:
When checking an application of function trans:
Type mismatch between
mult 2 (power 2 n' * power 2 m') = mult 2 (power 2 (n' + m')) (Type of cong powExp)
and
mult (mult 2 (power 2 n')) (power 2 m') = plus (power 2 (plus n' m')) (plus (power 2 (plus n' m')) 0) (Expected type)
Specifically:
Type mismatch between
mult 2 (power 2 (n' + m'))
and
plus (power 2 (plus n' m')) (plus (power 2 (plus n' m')) 0)
Насколько я могу судить, это, по сути, говорит о том, что он видит 2 * 2^(n+m)
там, где он хочет 2^(n+m) + (2^(n+m) + 0)
. Однако, по определению мульт, первое должно тривиально сводиться ко второму. В частности, следующие без проблем компилируются:
foo : 2 * a = a + (a + 0)
foo = Refl
Для меня это означает, что расширение работает так, как я ожидал. Но по какой-то причине в моей реализации expLaw
компилятор застрял. Мне интересно, может ли это быть как-то связано с использованием mult
и plus
против *
и +
, но я не уверен. Как я могу это исправить?
В качестве альтернативы, если у кого-то есть лучший способ реализовать expLaw
, я буду рад это услышать.