4

I'm just getting started in Isabelle and I'm getting a type unification error while working through Exercise 3.3 in of Concrete Semantics:

Define a substitution function

subst :: vname ⇒ aexp ⇒ aexp ⇒ aexp

such that subst x a e is the result of replacing every occurrence of variable x by a in e. For example:

subst ''x'' (N 3) (Plus (V ''x'') (V ''y'')) = Plus (N 3) (V ''y'')

Here's what I've got so far:

theory Scratchpad
imports Main
begin

type_synonym vname = string
type_synonym val = int
type_synonym state = "vname ⇒ val"

datatype aexp = N int | V vname | Plus aexp aexp
    
fun subst :: "vname ⇒ aexp ⇒ aexp ⇒ aexp" where
"subst x (N a) (N e) = (N e)" |
"subst x (N a) (V e) = (if x=e then (N a) else (V e))" |
"subst x (N a) (Plus e1 e2) = Plus(subst(x (N a) e1) subst(x (N a) e2))"

end

When the third case in the function definition is commented out, running the test cases

value "subst ''x'' (N 3) (N 5)"
value "subst ''x'' (N 3) (V ''x'')"

produces (N 5) and (N 3) respectively, so I know the first two lines are working correctly. Adding the last line results in the error

Type unification failed: Clash of types "_ ⇒ _" and "_ list"

Type error in application: operator not of function type

Operator: x :: char list
Operand: N a :: aexp

I don't think this is a syntax issue, although I'm not yet completely sure what purposes different types of quotation marks serve (e.g. double quotes vs. two single quotes). From this answer, I believe that Isabelle is assigning x to be a function type on the right side of the line, which is not what I want.

What do the error messages actually mean (specifically and generally), and how do I fix this?

Community
  • 1
  • 1

1 Answers1

4

To answer your question about quotes: Two single quotes are used in Isabelle/HOL (more precisely its inner syntax) to denote string literals. That is, by ''abc'' we denote the string containing the three characters a, b, and c (which would again use some special syntax if you had to enter them literally). Double quotes on the other hand, are mostly used to separate Isar statements (outer syntax) from terms inside the logic. So while ''...'' is part of the term language, "..." is not.

Now for the error message. It tells you that you are trying to use the list x (type _ list) as a function (type _ => _). Why does Isabelle think you want to use x as a function? Well, because juxtaposition (i.e., writing terms next to each other, separated by white space) denotes function application. Thus x (N a) is interpreted as applying a function x to an argument (N a) (just as f y is the application of f to the argument y). In order to give your definition the correct meaning you have to use parenthesis at the right positions. I guess what you intended in your third clause was:

Plus (subst x (N a) e1) (subst x (N a) e2)

where we have two occurrences of the function subst applied to three arguments. (So it was a syntax issue after all ;).)

Another comment. Your implementation of subst could be more general. As is, the second argument of subst is always fixed to be some number a (because of your usage of the constructor N). However, everything should work just as well if you would allow arbitrary expressions of type aexp.

chris
  • 4,988
  • 20
  • 36
  • This deserves a vote up, but I don't have 15 reputation yet. I'll have to remember to come back after I do. You're spot-on about the error with the parentheses. I've actually noticed and fixed it in simpler cases, but couldn't see it in this case. Maddening. One follow-up: could you define the phrase "term language"? I'm still hazy at best on the difference between Isabelle, HOL and Isar, and levels of syntax. – user3376010 Feb 01 '15 at 18:29
  • In order to answer your question about the *term language*, I refer to chapter 7 "Inner Syntax - The Term Language" of the [Isabelle/Isar Reference Manual](http://isabelle.in.tum.de/dist/Isabelle2014/doc/isar-ref.pdf). – chris Feb 02 '15 at 11:18