0

I have this function testing wether an element is in a binary tree or not:

fun lookup::"int⇒bst⇒bool" where
"lookup x _ = false" |
"lookup x bst = ( if x = root(bst) then true else if x≤root(bst) then lookup x left(bst)  else    lookup x right(bst))" 

I get the error message Type unification failed: Clash of types "bst" and "int"

The datatype bst is defined as

  datatype bst  = Leaf | Node int bst bst

What is wrong here?

Sophie Sepp
  • 521
  • 1
  • 5
  • 16
  • What are the types of `root`, `left` and `right`? – Alexander Kogtenkov Oct 27 '14 at 14:54
  • BTW, the function always returns `false`, because the first pattern always matches. – Alexander Kogtenkov Oct 27 '14 at 14:56
  • 1
    You should show a complete working example of a THY, so that, among other things, it will show the `imports`. You're using 4 functions there, `root`, `lookup`, `left`, and `right`. If they're your own, then people need to know the types. If they're from `src/HOL`, there's a lot in `Complex_Main` that people don't use, or in the library THYs that people don't import, use, or even know about. –  Oct 27 '14 at 15:14
  • imports Main Tree, no other functions defined, thought they were predefined. – Sophie Sepp Oct 27 '14 at 15:35
  • I also thought to define the function like this `fun lookup::"int⇒bst⇒bool" where "lookup x Leaf =(if x=Leaf then true else false)" | "lookup x (a leftbst rightbst) = ( if x = a then true else if x≤a then lookup x leftbst else lookup x rightbst)" ` but I generally don`t understand the problem with 'Clash of types "bst" and "int", or what should I write instead of x that it is considered as int, or for bst that it is considered as bst – Sophie Sepp Oct 27 '14 at 15:38
  • I also think you don`t need helping functions for the function if you use the definition of the datatype bst. – Sophie Sepp Oct 27 '14 at 15:55

2 Answers2

1

It looks like your datatype declaration does not mention any associated value for a leaf. So, it might look like

datatype_new bst  = Leaf int | Node int bst bst

Then the function just checks all the constructors of the current node:

fun lookup :: "int ⇒ bst ⇒ bool" where
    "lookup x (Leaf y) = x = y" |
    "lookup x (Node y leftbst rightbst) =
        (if x = y then True
         else (if x ≤ y then lookup x leftbst else lookup x rightbst))"
Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35
0

The short answer is that you're misusing root. It's NthRoot.root, from src/HOL/NthRoot.thy, and the type of root is shown in the error message:

root :: nat => real => real

I CNTL-clicked on root, and it took me to the function in NthRoot.thy.

From here, I basically complain that you made me work harder than I wanted, to answer your question, and even now, I'm assuming that I made me a THY which is duplicating what you're talking about.

You gave me this phrase in your comment: "imports Main Tree". However, after making a THY using only Main, the THY is obviously not what you're doing, because I don't get the error message Type unification failed: Clash of types "bst" and "nat".

theory Scratch
imports Main "~~/src/HOL/Library/Tree"
begin
datatype bst  = Leaf | Node int bst bst

fun lookup :: "int ⇒ bst ⇒ bool" where
  "lookup x _ = false" |
  "lookup x bst = (if x = root(bst) then true else if x ≤ root(bst)
                   then lookup x left(bst)  else    lookup x right(bst))"              
end

Also, in that THY, root is not defined, it's a variable. I saw that in two ways. I tried to CNTL-click on it, and nothing happened. I then noticed that it's blue, which means it's a local variable.

So, I imported Complex_Main like the following, and I got the error message that you're talking about. I know nothing much about binary trees, but the type of root shown in the error message can quickly tell you that root is most likely not what you want, since it's using real.

theory Scratch2
imports Complex_Main
begin
datatype bst  = Leaf | Node int bst bst

fun lookup :: "int => bst => bool" where
  "lookup x _ = false" |
  "lookup x bst = (if x = root(bst) then true else if x ≤ root(bst) 
                   then lookup x left(bst)  else    lookup x right(bst))"
(*Type unification failed: Clash of types "bst" and "nat"

  Type error in application: incompatible operand type

  Operator:  root :: nat => real => real*)
end

Anyway, people don't want to see too much source in questions, and they don't want to see too little. If you provide the magic amount, and all they have to do is cut and paste, then they don't have to work as hard to answer your question.

From your last question, Predefined functions for Binary trees in Isabelle, I knew where to get Tree from what Andreas said.

Andreas is the answer man for people like me and you. If you want to increase the chances of someone like him answering questions, then you want him to have to work as little as possible to figure out your question.

A minimal working example can help make sure everyone is on the same page, and even catch some mistakes on your end before you ask a question.

  • I will keep that in mind. @Alexander: This is my code using your function: `theory Ex02 imports Main Tree begin datatype_new bst = Leaf int | Node int bst bst fun lookup :: "int ⇒ bst ⇒ bool" where "lookup x (Leaf y) = (x = y)" | "lookup x (Node y leftbst rightbst) = (if x = y then true else (if x ≤ y then lookup x leftbst else lookup x rightbst))"end ` The error message I get is "Variable "true" occurs on right handside only". – Sophie Sepp Oct 27 '14 at 18:16
  • @user2057890: I misspelled it - it should be `True`. – Alexander Kogtenkov Oct 27 '14 at 18:29
  • @user2057890 Also, in that case neither type nor function use the theory _Tree_, so you can exclude it from your theory (unless you want to use the trees from there, not yours). – Alexander Kogtenkov Oct 27 '14 at 18:36