SymbolicUtils.jl icon indicating copy to clipboard operation
SymbolicUtils.jl copied to clipboard

incorrect computations for number types that are not of characteristic 0

Open matthias314 opened this issue 3 years ago • 2 comments

Assume that I define a type Bit <: Number for integers mod 2 (so that x + x == zero(Bit) for any x::Bit). Then I get

@syms x::Bit
x+x  # gives 2x instead of 0

I guess the problem is that in +(a::SN, b::SN) (and many other places in types.jl) you use 0 and 1 instead of zero(T) and one(T).

Code for `Bit`
import Base: +, -, *, /, zero, one, show

struct Bit <: Number
    x::Bool
end

+(a::Bit) = a
+(a::Bit, b::Bit) = Bit(xor(a.x, b.x))
-(a::Bit) = a
-(a::Bit, b::Bit) = a + b
*(a::Bit, b::Bit) = Bit(a.x & b.x)
/(a::Bit, b::Bit) = iszero(b.x) ? error("division by 0") : a

zero(::Type{Bit}) = Bit(0)
one(::Type{Bit}) = Bit(1)

show(io::IO, a::Bit) = print(io, iszero(a.x) ? '0' : '1')

matthias314 avatar Jul 30 '21 19:07 matthias314

I'm open to the zero and one change. Would you be willing to make a PR for this?

I think my general answer is that the package defining Bit and using it symbolically is responsible for making sure that arithmetic on them work correctly (in other words, they should define more specific methods on operations.)

shashi avatar Aug 27 '21 18:08 shashi

I'm willing to give it a try, although I don't know how much there is to do. Do you think that there are changes outside of types.jl required?

matthias314 avatar Aug 29 '21 22:08 matthias314