0

I am attempting to get an int list of coefficients of a remainder of the division of two polynomials. I have been attempting to use mod from Polynomial.thy on two polynomials of type int poly. However, I am getting the error:

Type unification failed: No type arity int :: field

My function is:

fun testFunc :: "int poly ⇒ int poly ⇒ int list"
where
  "testFunc p q = int_list (coeffs (p mod q))"

Where int_list simply converts a list of reals to a list of ints by flooring each element:

fun int_list :: "real list ⇒ int list"
where
  "int_list [] = []" |
  "int_list lst = [floor (hd lst)] @ int_list (tl lst)"

This works when I define my function as:

fun testFunc :: "'a::field poly ⇒ 'a poly ⇒ int list"
where
  "testFunc p q = int_list (coeffs (p mod q))"

However, the two arguments being passed into the function are specifically of type int poly. If I pass in two polynomials 'a::field poly and 'a poly using the second definition, then an 'a list is returned and I cannot run my int_list function.

If I change int_list's signature to 'a list => int list, then I must use int_of on each element, which ultimately does not evaluate the integers in my list. (i.e. I get something like [int_of 2, int_of 3] rather than [2, 3], and when I try to do something with those lists, it is returned with the int_of x expression rather than an evaluation)

Is it possible to get an int list of the coefficients of the modulo of two polynomials?

twasbrillig
  • 17,084
  • 9
  • 43
  • 67

1 Answers1

1

The floor function requires a type that's been instantiated as class floor_ceiling (Archimedean_Field.thy#l140).

So, I make your int_list as general as possible with 'a::floor_ceiling:

fun int_list :: "'a::{floor_ceiling} list => int list" where
  "int_list [] = []" |
  "int_list lst = [floor (hd lst)] @ int_list (tl lst)"

The type poly has been instantiated for class ring_div, which gives it the mod function, but only for 'a::field (Polynomial.thy#l1467).

Because testFunc uses int_list, I make your testFunc as general as possible with 'a::{field,floor_ceiling}:

fun testFunc :: "'a::{field,floor_ceiling} poly => 'a poly => int list"
  where
  "testFunc p q = int_list (coeffs (p mod q))"

value "testFunc ([:1,2,3:]::real poly) ([:5,6,7:]::real poly)"
  (*OUTPUT: "[- (2::int), - (1::int)]" :: "int list" *)

A few information commands:

declare[[show_sorts, show_consts]]
print_classes 
  (*At 'class ring_div', it shows ' poly :: (field) ring_div'.*)  
print_dependencies floor_ceiling  
print_dependencies ring_div