I've tried w/ different symbols but cannot get my prefix notation to work (infix, on the other hand, works). I guess it's a level problem but couldn't sort it out. Any ideas?
Variable (X R: Type)(x:X)(r:R).
Variable In: X -> R -> Prop.
Variable rt:> R -> Type.
Variable rTr: forall (x:X)(y:R), In x y -> y.
Notation "' a b" := (rTr a b I) (at level 9).
(* Check ' x r. -- Syntax error: [constr:operconstr] expected after
[constr:operconstr level 200] (in [constr:operconstr]). *)
Notation "a ' b" := (rTr a b I) (at level 9).
Fail Check x ' r. (* Works (half-compiles) *)
Print Grammar constr.
(* ...
| "9" LEFTA
[ SELF; "'"; NEXT
| "'"; constr:operconstr LEVEL "200"; NEXT
... *)
The trick was to specify a's level at least as low as that of '. Also, both had to be less than 10:
Notation "' a b" := (rTr a b I) (at level 9, a at level 9).
Fail Check ' x r. (* Works (half-compiles) *)
Also, the abbreviation version of the prefix notation worked w/out problems (the only annoyance being that symbols are barred in abbreviations):
Notation T a b := (rTr a b I).
Fail Check T x r. (* Works (half-compiles) *)
Related
Here is my simple locale definition in Isabelle:
locale sig =
fixes le:: "'a ⇒ 'a ⇒ bool" (infixl "≤" 50)
assumes refl: "x ≤ x"
Now, I get an error message:
Ambiguous input⌂ produces 2 parse trees:
("\<^const>HOL.Trueprop"
("\<^const>Orderings.ord_class.less_eq" ("_position" x) ("_position" x)))
("\<^const>HOL.Trueprop" ("\<^fixed>le" ("_position" x) ("_position" x)))
Ambiguous input
2 terms are type correct:
(x ≤ x)
(x ≤ x)
Failed to parse prop
Do I have a conflict with a builtin less-or-equal operator?
How can I fix this?
The ≤ operator is defined in the ord typeclass, so you could just extend this class:
class sig = ord +
assumes refl: "x ≤ x"
Other alternatives:
Do not import the definition of ord
Hide the existing notation with no_notation Orderings.ord_class.less_eq ("(_/ ≤ _)" [51, 51] 50) (see hiding operators to avoid ambiguities in the AST)
Use a different name or symbol
I am trying to capture the fact that there's an induced partial ordering in any idempotent semiring in Isabelle/HOL but am having trouble working out the best/correct way to do it.
I define:
class idem_semiring_1 = semiring_1 +
assumes idem [algebra_simps]: ‹a + a = a›
begin
definition less_eq :: ‹'a ⇒ 'a ⇒ bool›
where ‹less_eq a b ⟷ a + b = b›
definition less :: ‹'a ⇒ 'a ⇒ bool›
where ‹less a b ⟷ less_eq a b ∧ ¬ less_eq b a›
end
Now, it's straightforward to demonstrate that less_eq and less satisfy all of the laws of the order type class. However, is there a way of convincing Isabelle/HOL that any instance of idem_semiring_1 is also necessarily an instance of order using these definitions, so that the following query type-checks?
term ‹(y::'a::{idem_semiring_1}) ≤ x›
No combination of subclass, sublocale, etc., incantations seems to achieve what I want. In particular, the following:
sublocale idem_semiring_1 ⊆ order less_eq less
by (standard; clarsimp simp add: algebra_simps less_eq_def less_def) (metis add.assoc)
seems to work, as in the following lemmas become trivially provable via simp:
lemma
fixes x::‹'a::{idem_semiring_1}›
shows ‹less_eq x x›
by simp
lemma
assumes ‹less_eq x y›
and ‹less_eq y z›
shows ‹less_eq x z›
using assms by simp
but the following does not type-check:
lemma
fixes x :: ‹'a::{idem_semiring_1}›
shows ‹x ≤ x›
What am I not doing to convince Isabelle to connect the ≤ syntax with the less_eq definition?
What if you defined idem_semiring_1 like this:
class idem_semiring_1 = semiring_1 + order +
assumes idem [algebra_simps]: ‹a + a = a› and
less_eq_idem_semiring_1: ‹a ≤ b ⟷ a + b = b›
I have written a parser in Haskell, which parses formulas in the form of string inputs and produces a Haskell data type defined by the BNF below.
formula ::= true
| false
| var
| formula & formula
| ∀ var . formula
| (formula)
var ::= letter { letter | digit }*
Now I would like to create an instance of Show so that I can nicely print the formulas defined by my types (I don't want to use deriving (Show)). My question is: How do I define my function so that it can tell when parentheses are necessary? I don't want too many, nor too little parentheses.
For example, given the formula ∀ X . (X & Y) & (∀ Y . Y) & false which, when parsed, produces the data structure
And (And (Forall "X" (And (Var "X") (Var "Y"))) (Forall "Y" (Var "Y"))) False
we have
Too little parentheses: ∀ X . X & Y & ∀ Y . Y & false
Too much parentheses: (∀ X . (((X) & (Y)))) & (∀ Y . (Y)) & (false)
Just right: ∀ X . (X & Y) & (∀ Y . Y) & false
Is there a way to gauge how many parenthesis are necessary so that the semantics is never ambiguous? I appreciate any feedback.
Untested pseudocode:
instance Show Formula where
showsPrec _p True = "True"
showsPrec _p False = "False"
showsPrec p (And f1 f2) = showParen (p > 5) $
showsPrec 5 f1 . (" & " ++) . showsPrec 5 f2
showsPrec p (Forall x f) = showParen (p > 8) $
("forall " ++ x ++) . showsPrec 8 f
...
(I should probably use showString instead of those ++ above. It should work anyway, I think.)
Above, the integer p represents the precedence of the context where we are showing the current formula. For example, if we are showing f inside f & ... then p will have the precedence level of &.
If we need to print a symbol in a context which has higher precedence, we need to add parentheses. E.g. if f is a | b we can't write a | b & ..., otherwise it is interpreted as a | (b & ...). We need to put parentheses around a | b. This is done by the showParen (p > ...).
When we recurse, we pass the precedence level of the symbol at hand to the subterms.
Above, I chose the precedence levels randomly. You need to adjust them to your tastes. You should also check that the levels you choose play along the standard libraries. E.g. printing Just someFormula should not generate things like Just a & b, but add parentheses.
I am using WxMaxima for some calculations so I can export the results directly into my LaTeX file. I have some Greek variables with Greek subscripts which are giving me a headache. In the past in Maxima I used to put the subscripts in the bracket []. But I have noticed that the conventional LaTeX syntax of _ also works. Except it doesn't work for greek letters:
So I have to use the brackets one [] when I want to subscript the Greek letters with Greek letters. But it is causing some calculation errors.
For example consider two simple functions:
%epsilon[r](r):=c[1]-c[2]/r^2;
%epsilon[%theta](r):=c[1]+c[2]/r^2;
now if I run:
fullratsimp(%epsilon[r](r)+%nu*%epsilon[%theta](r));
it gives me:
((c[1]*%nu+c[1])*r^2+c[2]*%nu+c[2])/r^2
Which is obviously wrong because the correct result can be calculated by:
fullratsimp((c[1]-c[2]/r^2)+%nu*(c[1]+c[2]/r^2));
I would appreciate if you could help me know what is the problem and how I can solve it.
The problem is that foo[x1](y) := ... and foo[x2](y) := ... defines just one function foo, and the second definition clobbers the first one, so that only foo[x2](y) := ... is defined.
You can get the effect you want by creating lambda expressions (unnamed functions) and assigning them to subscripted variables.
(%i1) %epsilon[r](r):=c[1]-c[2]/r^2 $
(%i2) %epsilon[%theta](r):=c[1]+c[2]/r^2 $
(%i3) %epsilon[r];
c
2
(%o3) lambda([r], -- + c )
2 1
r
(%i4) %epsilon[%theta];
c
2
(%o4) lambda([r], -- + c )
2 1
r
(%i5) kill(%epsilon) $
(%i6) %epsilon[r] : lambda([r], c[1]-c[2]/r^2) $
(%i7) %epsilon[%theta] : lambda([r], c[1]+c[2]/r^2) $
(%i8) %epsilon[r];
c
2
(%o8) lambda([r], c - --)
1 2
r
(%i9) %epsilon[%theta];
c
2
(%o9) lambda([r], c + --)
1 2
r
(%i10) fullratsimp(%epsilon[r](r)+%nu*%epsilon[%theta](r));
2
(c %nu + c ) r + c %nu - c
1 1 2 2
(%o10) ------------------------------
2
r
Note that foo[x](y) := ... also creates lambda expressions, but you need to ensure your own definition here, not the definition which is created automatically by Maxima.
I'm working on creating maxima functions to simplify the del operator on vectors. How can I pass a list/vector to a function in maxima? This works:
(%i7) dot(a,b) := a[1]*b[1]+a[2]*b[2]+a[3]*b[3];
(%o7) dot(a, b) := a b + a b + a b
1 1 2 2 3 3
(%i8) dot(a,b);
2
(%o8) 3 x y - 4 x
but this doesn't:
(%i13) grad(a) := diff(a[1],x) + diff(a[2],y) + diff(a[3],z);
define: argument cannot be an atom or a subscripted memoizing function; found:
a
-- an error. To debug this try: debugmode(true);
Maxima has extremely confusing rules about scope and subscripts. First of all, I'll apologize for that.
My guess is that you already have an array named a by the time you define grad. Try a different name for the argument of grad -- try something which you haven't used yet. Does it work that way?
Anyway, shouldn't the definition be:
grad(a) := [diff(a, x), diff(a, y), diff(a, z)];
??