Type Unification failed for bool * bool ⇒ bool * bool - functional-programming

I wrote a simple function which should perform the function of a halfadder.
fun halfadder :: "bool * bool ⇒ bool * bool"
where
"halfadder (a,b) = (
let s = xor a b in
let cout = and a b in
(cout,s))"
However, I get the following error:
Type unification failed: No type arity bool :: semiring_bit_operations
Type error in application: incompatible operand type
Operator: xor :: ??'a ⇒ ??'a ⇒ ??'a
Operand: a :: bool
Why is it not able to perform a XOR operation on a bool? What is going wrong here?
I have tried using the XOR operator with different data types and it still faces the same error

The type bool in Isabelle/HOL is the type for logical formulas (of the object logic HOL) and so not intended to be used as a type for bit datas. For example, a diagnosis
term "P ∧ Q"
gives
"P ∧ Q"
:: "bool"
If you jump to the definition of xor, you find that xor is defined for (or fixed for or being a method of) the class semiring_bit_operations. A possible solution is to define your halfadder inside the context of semiring_bit_operations, e.g.
context semiring_bit_operations
begin
fun halfadder :: "'a * 'a ⇒ 'a * 'a"
where
"halfadder (a, b) = (
let s = xor a b in
let cout = and a b in
(cout,s))"
end
which worked for me.
However, semiring_bit_operations is not a class for one bits but bit sequences. Thus, it's better to define your own boolean datatype, and and xor (or use some built-in type if any (which I don't know)).
(Note: I'm a beginner of Isabelle and so it is probably better to wait for more comprehensive answers from specialists.)

Related

Definition of multiplicative group of a field in Isabelle

theory Scratch
imports
"HOL.Fields"
"HOL.Groups"
begin
locale Field_is_group=
fixes F :: "'a :: field"
begin
typedef 'a mul_group = "{x :: 'a set. x ≠ 0}"
end
end
I'm new to Isabelle, and I have learned something about proving in first-order logic but not about data structures. I tried to formalize the proof of the fact that a field has a multiplicative group, but I don't know how to define the multiplicative group. It is the set of the whole field except zero, and a field in Isabelle is defined as a type. By looking about the references, I know I need use typedef, but it fails:
Type unification failed: No type arity set :: zero
Failed to meet type constraint:
Term: λx. x ≠ 0 :: ??'b ⇒ bool
Type: 'a set ⇒ ??'a
The error(s) above occurred in typedef "mul_group"

Isabelle/HOL error Type unification failed: Clash of types "nat" and "_ set" Type error in application: incompatible operand type

Im really new to isabelle, this is my problem
theory MyTheory3
imports Main
begin
(* 3.1) a) define a type natpair, whose elements are pairs of natural numbers.*)
datatype natpair = Natpair "nat × nat"
(*3.1 b)define a function of type natpair ⇒ nat that returns the sum of the elements of a pair of natural
numbers.*)
definition natpair_sum :: "natpair ⇒ nat" where
"Natpair((a::nat) × (b::nat)) = a + b"
end
i get the error
Type unification failed: Clash of types "nat" and "_ set"
Type error in application: incompatible operand type
Operator: (×) :: ??'a set ⇒ ??'b set ⇒ (??'a × ??'b) set Operand: a
:: nat
in addition, can someone show me an example of natpair with a parameterized
constructor
Thanks in advance
youre nuric
Your code has several issues:
Operator (×) is not a constructor for pairs but the Cartesian product of sets; pairs are constructed using the syntax (a, b) or Pair a b.
The definition natpair_sum does not use its name in the equation, that is, the correct syntax is definition natpair_sum :: "natpair ⇒ nat" where "natpair_sum ... = ...".
Pattern matching is not allowed in the left-hand side of a definition; you can use the case construct in the right-hand side of the definition or you can use functions instead.
There is no need to add type annotations for the components of the pair.
As examples, here are two possible definitions for natpair_sum:
definition natpair_sum :: "natpair ⇒ nat" where
"natpair_sum np = (case np of Natpair (a, b) ⇒ a + b)"
fun natpair_sum :: "natpair ⇒ nat" where
"natpair_sum (Natpair (a, b)) = a + b"
As for your last question, I'm not quite sure what you mean by "an example of natpair with a parameterized constructor". Natpair is already a data constructor which takes a pair of nat's as the only parameter.

Isabelle/Simpl: Type unification failed using hoarestate

I started using Isabelle/Simpl and write the following theory according to the user guide:
theory Scratch
imports Simpl.Simpl
begin
hoarestate newvars =
N :: nat
lemma (in newvars) "Γ ⊢ {} ´N :== ´N + 1 {}"
sorry
end
But Isabelle complains that type unification fails:
Type unification failed
Type error in application: operator not of function type
Operator: N_' :: 'a
Operand: s :: ??'a
Simpl itself (including its user guide) successfully compiles.
How can I make it pass?
As Javier Díaz pointed out, importing only Simpl.Vcg instead of Simpl.Simpl does the trick.
The cause of the error seems a name collision against a record defined in Simpl.SyntaxTest. It contains the following record definition:
record 'g vars = "'g state" +
A_' :: "nat list"
AA_' :: "nat list list"
I_' :: nat
M_' :: nat
N_' :: nat
R_' :: int
S_' :: int
B_' :: bool
Abr_':: string
p_' :: ref
q_' :: ref
Isabelle seems to prefer N_' in the record to N in the hoarestate, although the hoarestate is defined later😥. I don't know why this is the case.

Is it a good idea to extend standard types and operations?

I need to defined an extended bool type (ebool = bool ∪ {⊥}) and a set of operations for the type (conjunction, etc.).
Here is the theory:
theory EboolTest
imports Main "~~/src/HOL/Library/Adhoc_Overloading"
begin
notation
bot ("⊥")
declare [[coercion_enabled]]
typedef ebool = "UNIV :: bool option set" ..
definition ebool :: "bool ⇒ ebool" where
"ebool b = Abs_ebool (Some b)"
declare [[coercion "ebool :: bool ⇒ ebool"]]
instantiation ebool :: bot
begin
definition "⊥ ≡ Abs_ebool None"
instance ..
end
free_constructors case_ebool for
ebool
| "⊥ :: ebool"
apply (metis Rep_ebool_inverse bot_ebool_def ebool_def not_Some_eq)
apply (smt Abs_ebool_inverse ebool_def iso_tuple_UNIV_I option.inject)
by (simp add: Abs_ebool_inject bot_ebool_def ebool_def)
lemmas ebool2_cases = ebool.exhaust[case_product ebool.exhaust]
lemmas ebool3_cases = ebool.exhaust[case_product ebool.exhaust ebool.exhaust]
fun ebool_and :: "ebool ⇒ ebool ⇒ ebool" (infixr "∧" 35) where
"ebool_and a b = ebool (HOL.conj a b)"
| "ebool_and False _ = False"
| "ebool_and _ False = False"
| "ebool_and ⊥ _ = ⊥"
| "ebool_and _ ⊥ = ⊥"
no_notation HOL.conj (infixr "∧" 35)
consts "(∧)" :: "'a ⇒ 'a ⇒ 'a"
adhoc_overloading "(∧)" HOL.conj
adhoc_overloading "(∧)" ebool_and
end
The following works fine:
value "True ∧ (False::ebool)"
value "True ∧ ⊥"
But the following returns ebool, but I expect to see bool:
value "True ∧ False"
It seems my approach is bad. Could you suggest a better approach? Maybe I it's not good to overload standard operations at all?
First of all, I'm a little surprised that this:
consts "(∧)" :: "'a ⇒ 'a ⇒ 'a"
works at all. It sounds like a bug, because the (...) notation is reserved for the system. (To be fair, it does print a warning, and unless you know exactly what you're doing, it's unwise to ignore them.)
But to circle back to your actual problem, I don't think you should use adhoc_overloading to overload syntax that would otherwise be provided by Main.
There are alternatives. For example, you could use a bold version. This is used in this theory.
Or you could use another symbol, like &&.
As an addendum: I believe there might be weird interactions between coercions and adhoc overloading. Both tools are fine by themselves, but watch out if they interact with each other.

Exporting code from locales with multiple parameters

according to the codegen documentation section "7.3 Locales and interpretation", exporting code from locales is a bit tricky but achievable. The following example works fine:
locale localTest =
fixes A :: "string"
begin
fun concatA :: "string ⇒ string" where "concatA x = x#A"
definition concatAA :: "string ⇒ string" where "concatAA x = x#A#A"
end
definition localtest_concatA :: "string ⇒ string " where
[code del]: "localtest_concatA = localTest.concatA ''a''"
definition localtest_concatAA :: "string ⇒ string " where
[code del]: "localtest_concatAA = localTest.concatAA ''a''"
interpretation localTest "''a''"
where "localTest.concatA ''a'' = localtest_concatA"
and "localTest.concatAA ''a'' = localtest_concatAA"
apply unfold_locales
apply(simp_all add: localtest_concatA_def localtest_concatAA_def)
done
export_code localtest_concatA localtest_concatAA in Scala file -
How can I export code for locales with multiple parameters? Given the following locale:
locale localTest =
fixes A :: "string"
fixes B :: "string"
begin
fun concatA :: "string ⇒ string" where "concatA x = x#A"
definition concatB :: "string ⇒ string" where "concatB x = x#B"
end
I can interpret it with
interpretation localTest "''a''" "''b''" .
But I canot use this interpretation in a definition
definition localtest_concatA :: "string ⇒ string " where
[code del]: "localtest_concatA = localTest.concatA ''a'' ''b''"
It fails with
Type unification failed: Clash of types "_ list" and "_ ⇒ _"
Type error in application: incompatible operand type
Operator: op = localtest_concatA :: (char list ⇒ char list) ⇒ bool
Operand: localTest.concatA ''a'' ''b'' :: char list
Look at your introduced constants, e.g., by the term command. We have
term localTest.concatA
with output
"localTest.concatA" :: "char list ⇒ char list ⇒ char list"
You see that in addition to the single parameter that you gave in the original definition (inside the locale), there is an additional one (but only 1 not 2, since the definition does not rely on B).
Now, after your interpretation (since you did not explicitly provide a name, the constants of localTest will be in scope without qualifier) we have
term concatA
with output
"localTest.concatA ''a''" :: "char list ⇒ char list"
That is, localTest.concatA ''a'' is already of type string => string. You additionally add ''b'' and obtain type string, but your type annotation says string => string. So there is really a clash of types and the reason was that you gave too many arguments to localTest.concatA. Try using
definition localtest_concatA :: "string ⇒ string " where
[code del]: "localtest_concatA = concatA
instead.

Resources