Defining a quotient_type in Isabelle - equality

I'm still trying to reason over semantic equality in Isabelle.
I want to compare two formula and see whether they are equal. I've been told before, that i need quotienttypes for this.
So i tried to define myself a quotiernttype, but apperently my definition is not complete since i don't seem to be abled to write any code after my definition.
My code so far is:
theory Scratch
imports Main
begin
no_notation plus (infixl "+" 65)
typedecl basicForm
datatype form_rep = af basicForm
axiomatization
equals :: "form_rep ⇒ form_rep ⇒ bool" (infix "≐" 1) and
plus :: "form_rep ⇒ form_rep ⇒ form_rep" (infixl "+" 35)
where
reflexive: "x ≐ x" and
symmetric: "x ≐ y ⟹ y ≐ x" and
transitiv: "x ≐ y ⟹ y ≐ z ⟹ x ≐ z" and
commut: "x + y ≐ y + x" and
associatPlus: "(x + y) + z ≐ x + (y + z)" and
idemo: "x + x ≐ x"
quotient_type formula = "form_rep" / "equals"
I've got some basic formula and complex version of it and i want to reason over the complex type, thus i defined equals with the three axioms for equality relations and 3 additional easy axioms.
edit: Aparently i am an idiot who forgot to add quotationmarks -.-
still don't know how to continue from here on thought.

The quotient_type commands requires a proof to be finished properly. See the proof state output what needs to be proven. Such things are explicitly or implicitly explained in the isar-ref manual.
Unrelated notes:
Better avoid re-using elementary notation like +. The Symbols panel in the Prover IDE provides plenty of alternatives.
Better avoid free-form axiomatization, especially for initial examples. Just take what Isabelle/HOL provides already, and make definitions on top of that (datatype, definition, inductive, fun etc.)
Camel-case is not used in Isabelle.

Related

Term equality in Isabelle

Is there already some term equality relation defined in Isabelle? What is the broadest set of terms on which it is defined?
Just to be clear, I'm looking for a relation a ~ b that returns True iff a is b in the sense that they look exactly the same written down: no properties of a and b should need to be known to evaluate a ~ b.
No such thing exists. There's no notion of syntactic equality in the logic, because it admits definitions (x ≡ T) and substitution (x ≡ y ⇒ P x ≡ P y).
What you could do instead is use ML's equality operator on terms. But for that, you have to use ML blocks.

Where is the Idris == operator useful?

As a beginner in type-driven programming, I'm curious about the use of the == operator. Examples demonstrate that it's not sufficient to prove equality between two values of a certain type, and special equality checking types are introduced for the particular data types. In that case, where is == useful at all?
(==) (as the single constituent function of the Eq interface) is a function from a type T to Bool, and is good for equational reasoning. Whereas x = y (where x : T and y : T) AKA "intensional equality" is itself a type and therefore a proposition. You can and often will want to bounce back and forth between the two different ways of expressing equality for a particular type.
x == y = True is also a proposition, and is often an intermediate step between reasoning about (==) and reasoning about =.
The exact relationship between the two types of equality is rather complex, and you can read https://github.com/pdorrell/learning-idris/blob/9d3454a77f6e21cd476bd17c0bfd2a8a41f382b7/finished/EqFromEquality.idr for my own attempt to understand some aspects of it. (One thing to note is that even though an inductively defined type will have decideable intensional equality, you still have to go through a few hoops to prove that, and a few more hoops to define a corresponding implementation of Eq.)
One particular handy code snippet is this:
-- for rel x y, provide both the computed value, and the proposition that it is equal to the value (as a dependent pair)
has_value_dpair : (rel : t -> t -> Bool) -> (x : t) -> (y : t) -> (value: Bool ** rel x y = value)
has_value_dpair rel x y = (rel x y ** Refl)
You can use it with the with construct when you have a value returned from rel x y and you want to reason about the proposition rel x y = True or rel x y = False (and rel is some function that might represent a notion of equality between x and y).
(In this answer I assume the case where (==) corresponds to =, but you are entirely free to define a (==) function that doesn't correspond to =, eg when defining a Setoid. So that's another reason to use (==) instead of =.)
You still need good old equality because sometimes you can't prove things. Sometimes you don't even need to prove. Consider next example:
countEquals : Eq a => a -> List a -> Nat
countEquals x = length . filter (== x)
You might want to just count number of equal elements to show some statistics to user. Another example: tests. Yes, even with strong type system and dependent types you might want to perform good old unit tests. So you want to check for expectations and this is rather convenient to do with (==) operator.
I'm not going to write full list of cases where you might need (==). Equality operator is not enough for proving but you don't always need proofs.

Well typed and ill typed lambda terms

I have been trying to understand the applied lambda calculus. Up till now, I have understood how type inference works. But I am not able to follow what is the meaning of saying that a term is well-typed or ill-typed and then how can I determine whether a given term is well-typed or ill-typed.
For example, consider a lambda term tw defined as λx[(x x)] . How to conclude whether it is a well-typed or ill-typed term?
If we are talking about Simply Typed Lambda Calculus with some additional constants and basic types (i.e. applied lambda calculus), then the term λx:σ. (x x) is well-formed, but ill-typed.
'Well-formed' means syntactically correct, i.e. will be accepted by a parser for STLC. 'Ill-typed' means the type-checker would not pass it further.
Type-checker works according to the typing rules, which are usually expressed as a number of typing judgements (one typing scheme for each syntactic form).
Let me show that the term you provided is indeed ill-typed.
According to the rule (3) [see the typing rules link], λx:σ. (x x) must have type of general form σ -> τ (since it is a function, or more correctly abstraction). But that means the body (x x) must have some type τ (assuming x : σ). This is basically the same rule (3) expressed in a natural language. So, now we need to figure out the type of the function's body, which is an application.
Now, the rule for application (4) says that if we have an expression like this (e1 e2), then e1 must be some function e1 : α -> β and e2 : α must be an argument of the right type. Let's apply this rule to our expression for the body (x x). (1) x : α -> β and (2) x : α. Since an term in STLC can have only one type, we've got an equation: α -> β = α.
But there is no way we can unify both types together, since α is a subpart of α -> β. That's why this won't typecheck.
By the way, one of the major points of STLC was to forbid self-application (like (x x)), because it prevents from using (untyped) lambda calculus as a logic, since one can perform non-terminating calculations using self-application (see for instance Y-combinator).

Decidability of propositional equaility

Two terms in agda are said to be definitionally equal precisely when they both have the same normal form ---I think---, and propositional equality is just the data-type representation of definitional equality ---again, I guess---; so then shouldn't propositionally equality be decidable? That is, would it seem reasonable that we can write a function typed
∀{A : Set} → (x y : A) → Dec(x ≡ y).
I kinda of get that we cannot write such a function since we cannot pattern match on the arguments, but I 'feel' that it should be possible: again, just reduce to normal form and check for syntactic identity.
Any insight would be helpful!
Two terms in agda are said to be definitionally equal precisely when
they both have the same normal form
Up to αη-conversion.
and propositional equality is just the data-type representation of definitional equality
Propositional equality says "these two terms will become definitionally equal after you instantiate some free variables" ("some" can be 0 or all of them) ("instantiate" can vary too).
E.g.
double-double : (n : ℕ) -> n + n ≡ 2 * n
clearly, n + n is not syntactically equal to 2 * n, but for any canonical n (0, 1, 2...) the result of n + n is syntactically equal to the result of 2 * n — that's what double-double says. And that "for any canonical n" part forces us to prove double-double by induction (though, in a more complicated system, where definitional equality is based on supercompilation or there is a build-in prover, n + n is definitionally equal to 2 * n).
But sometimes it's not as obvious how an induction hypothesis should look like, e.g. when you need to generalize an equation. As you might expect, there is no decision procedure for "is this arbitrary thing provable?" and hence propositional equality is undecidable. Moreover, you can't neither prove nor disprove statements like
(λ n -> 1 + n) ≡ (λ n -> n + 1)
without additional postulates.
However you really can check for syntactic equality:
_≟_ : ∀ {α} {A : Set α} -> (x y : A) -> Maybe (x ≡ y)
It says "if two terms are syntactically equal, then they are equal propositionally, otherwise we don't know whether they are equal propositionally or not". But Agda doesn't have such built-in function.

Equivalent of define-fun in Z3 API

Using Z3 with the textual format, I can use define-fun to define functions for reuse later on. For example:
(define-fun mydiv ((x Real) (y Real)) Real
(if (not (= y 0.0))
(/ x y)
0.0))
I wonder how to create define-fun with Z3 API (I use F#) instead of repeating the body of the function everywhere. I want to use it to avoid duplication and debug formulas easier. I tried with Context.MkFuncDecl, but it seems to generate uninterpreted functions only.
The define-fun command is just creating a macro. Note that the SMT 2.0 standard doesn’t allow recursive definitions.
Z3 will expand every occurrence of my-div during parsing time.
The command define-fun may be used to make the input file simpler and easier to read, but internally it does not really help Z3.
In the current API, there is no support for creating macros.
This is not a real limitation, since we can define a C or F# function that creates instances of a macro.
However, it seems you want to display (and manually inspect) formulas created using the Z3 API. In this case, macros will not help you.
One alternative is to use quantifiers. You can declare an uninterpreted function my-div and assert the universally quantified formula:
(declare-fun mydiv (Real Real) Real)
(assert (forall ((x Real) (y Real))
(= (mydiv x y)
(if (not (= y 0.0))
(/ x y)
0.0))))
Now, you can create your formula using the uninterpreted function mydiv.
This kind of quantified formula can be handled by Z3. Actually, there are two options to handle this kind of quantifier:
Use the macro finder: this preprocessing step identifies quantifiers that are essentially defining macros and expand them. However, the expansion only happens during preprocessing time, not during parsing (i.e., formula construction time). To enable the model finder, you have to use MACRO_FINDER=true
The other option is to use MBQI (model based quantifier instantiation). This module can also handle this kind of quantifier. However, the quantifiers will be expanded on demand.
Of course, the solving time may heavily depend on which approach you use. For example, if your formula is unsatisfiable independently of the “meaning” of mydiv, then approach 2 is probably better.