11import Leanwuzla.Aux
22import Leanwuzla.Sexp
3+ import Fp
34
45open Lean
56
@@ -23,16 +24,44 @@ abbrev ParserM := StateT Parser.State (Except MessageData)
2324namespace Parser
2425
2526private def mkBool : Expr :=
26- .const `` Bool []
27+ toTypeExpr Bool
2728
2829private def mkBitVec (w : Nat) : Expr :=
29- .app (.const ``BitVec []) (mkNatLit w)
30+ toTypeExpr (BitVec w)
31+
32+ -- Temporary ToExpr instances for PackedFloat and RoundingMode
33+ deriving instance ToExpr for PackedFloat
34+ deriving instance ToExpr for RoundingMode
35+
36+ private def mkFloat (eb sb : Nat) : Expr :=
37+ toTypeExpr (PackedFloat eb sb)
38+
39+ private def mkRoundingMode : Expr :=
40+ toTypeExpr RoundingMode
41+
42+ private def mkFloat16 : Expr :=
43+ toTypeExpr (PackedFloat 5 (11 - 1 ))
44+
45+ private def mkFloat32 : Expr :=
46+ toTypeExpr (PackedFloat 8 (24 - 1 ))
47+
48+ private def mkFloat64 : Expr :=
49+ toTypeExpr (PackedFloat 11 (53 - 1 ))
50+
51+ private def mkFloat128 : Expr :=
52+ toTypeExpr (PackedFloat 15 (113 - 1 ))
3053
3154private def getBitVecWidth (α : Expr) : ParserM Nat := do
3255 match α with
3356 | .app (.const ``BitVec []) w => return w.nat?.get!
3457 | _ => throw m! "Error: expected BitVec type, got { α} "
3558
59+ private def getFloatEbSb (α : Expr) : ParserM (Nat × Nat) := do
60+ match α with
61+ | .app (.app (.const ``PackedFloat []) eb) sb =>
62+ return (eb.nat?.get!, sb.nat?.get!)
63+ | _ => throw m! "Error: expected PackedFloat type, got { α} "
64+
3665private def mkInstBEqBool : Expr :=
3766 mkApp2 (.const ``instBEqOfDecidableEq [0 ]) mkBool
3867 (.const ``instDecidableEqBool [])
@@ -41,6 +70,10 @@ private def mkInstBEqBitVec (w : Nat) : Expr :=
4170 mkApp2 (.const ``instBEqOfDecidableEq [0 ]) (mkBitVec w)
4271 (.app (.const ``instDecidableEqBitVec []) (mkNatLit w))
4372
73+ private def mkInstBEqFloat (eb sb : Nat) : Expr :=
74+ mkApp2 (.const ``instBEqOfDecidableEq [0 ]) (mkFloat eb sb)
75+ (mkApp2 (.const ``instDecidableEqPackedFloat []) (mkNatLit eb) (mkNatLit sb))
76+
4477private def mkBitVecAppend (w v : Nat) : Expr :=
4578 mkApp4 (.const ``HAppend.hAppend [0 , 0 , 0 ])
4679 (mkBitVec w) (mkBitVec v) (mkBitVec (w + v))
@@ -125,6 +158,20 @@ def parseSort (s : Sexp) : ParserM (Expr × Expr) := do
125158 | sexp!{(_ BitVec {w})} =>
126159 let w := w.serialize.toNat!
127160 return (mkBitVec w, mkBitVec w)
161+ | sexp!{(_ FloatingPoint {eb} {sb})} =>
162+ let eb := eb.serialize.toNat!
163+ let sb := sb.serialize.toNat!
164+ return (mkFloat eb (sb - 1 ), mkFloat eb (sb - 1 ))
165+ | sexp!{Float16} =>
166+ return (mkFloat16, mkFloat16)
167+ | sexp!{Float32} =>
168+ return (mkFloat32, mkFloat32)
169+ | sexp!{Float64} =>
170+ return (mkFloat64, mkFloat64)
171+ | sexp!{Float128} =>
172+ return (mkFloat128, mkFloat128)
173+ | sexp!{RoundingMode} =>
174+ return (mkRoundingMode, mkRoundingMode)
128175 | sexp!{({sc} ⦃as⦄)} =>
129176 let (bsc, sc) ← parseSort sc
130177 let as ← as.mapM parseSort
@@ -159,9 +206,9 @@ where
159206 let e := bindings.foldr (fun (n, t, v) b => .letE n t v b true ) b
160207 return (tb, e)
161208 if let sexp!{true } := e then
162- return (mkBool, .const `` true [] )
209+ return (mkBool, toExpr true )
163210 if let sexp!{false } := e then
164- return (mkBool, .const `` false [] )
211+ return (mkBool, toExpr false )
165212 if let sexp!{(not {p})} := e then
166213 let (_, p) ← parseTerm p
167214 return (mkBool, .app (.const ``not []) p)
@@ -180,6 +227,7 @@ where
180227 let (_, y) ← parseTerm y
181228 let hα ← if uα == mkBool then pure mkInstBEqBool
182229 else if uα.isAppOfArity ``BitVec 1 then pure (mkInstBEqBitVec (← getBitVecWidth uα))
230+ else if uα.isAppOfArity ``PackedFloat 2 then let (eb, sb) ← getFloatEbSb uα; pure (mkInstBEqFloat eb sb)
183231 else throw m! "Error: unsupported type for equality: { uα} "
184232 return (mkBool, mkApp4 (.const ``BEq.beq [0 ]) uα hα x y)
185233 if let sexp!{(distinct ⦃xs⦄)} := e then
@@ -351,6 +399,173 @@ where
351399 let (α, x) ← parseTerm x
352400 let w ← getBitVecWidth α
353401 return (α, mkApp3 (.const ``BitVec.rotateRight []) (mkNatLit w) x (mkNatLit i))
402+ if let sexp!{roundNearestTiesToEven} := e then
403+ return (mkRoundingMode, toExpr RoundingMode.RNE)
404+ if let sexp!{RNE} := e then
405+ return (mkRoundingMode, toExpr RoundingMode.RNE)
406+ if let sexp!{roundNearestTiesToAway} := e then
407+ return (mkRoundingMode, toExpr RoundingMode.RNA)
408+ if let sexp!{RNA} := e then
409+ return (mkRoundingMode, toExpr RoundingMode.RNA)
410+ if let sexp!{roundTowardPositive} := e then
411+ return (mkRoundingMode, toExpr RoundingMode.RTP)
412+ if let sexp!{RTP} := e then
413+ return (mkRoundingMode, toExpr RoundingMode.RTP)
414+ if let sexp!{roundTowardNegative} := e then
415+ return (mkRoundingMode, toExpr RoundingMode.RTN)
416+ if let sexp!{RTN} := e then
417+ return (mkRoundingMode, toExpr RoundingMode.RTN)
418+ if let sexp!{roundTowardZero} := e then
419+ return (mkRoundingMode, toExpr RoundingMode.RTZ)
420+ if let sexp!{RTZ} := e then
421+ return (mkRoundingMode, toExpr RoundingMode.RTZ)
422+ if let sexp!{(fp {sign} {ex} {sig})} := e then
423+ let some ⟨1 , sign⟩ := parseBVLiteral? sign | throw m! "Error: expected sign to be a bit-vector literal"
424+ let some ⟨eb, ex⟩ := parseBVLiteral? ex | throw m! "Error: expected exponent to be a bit-vector literal"
425+ let some ⟨sb, sig⟩ := parseBVLiteral? sig | throw m! "Error: expected significand to be a bit-vector literal"
426+ return (mkFloat eb sb, toExpr (PackedFloat.mk sign.msb ex sig))
427+ if let sexp!{(_ +oo {eb} {sb})} := e then
428+ let eb := eb.serialize.toNat!
429+ let sb := sb.serialize.toNat! - 1
430+ return (mkFloat eb sb, toExpr (PackedFloat.getInfinity eb sb false ))
431+ if let sexp!{(_ -oo {eb} {sb})} := e then
432+ let eb := eb.serialize.toNat!
433+ let sb := sb.serialize.toNat! - 1
434+ return (mkFloat eb sb, toExpr (PackedFloat.getInfinity eb sb true ))
435+ if let sexp!{(_ +zero {eb} {sb})} := e then
436+ let eb := eb.serialize.toNat!
437+ let sb := sb.serialize.toNat! - 1
438+ return (mkFloat eb sb, toExpr (PackedFloat.getZero eb sb false ))
439+ if let sexp!{(_ -zero {eb} {sb})} := e then
440+ let eb := eb.serialize.toNat!
441+ let sb := sb.serialize.toNat! - 1
442+ return (mkFloat eb sb, toExpr (PackedFloat.getZero eb sb true ))
443+ if let sexp!{(_ NaN {eb} {sb})} := e then
444+ let eb := eb.serialize.toNat!
445+ let sb := sb.serialize.toNat! - 1
446+ return (mkFloat eb sb, toExpr (PackedFloat.getNaN eb sb))
447+ if let sexp!{(fp.abs {x})} := e then
448+ let (α, x) ← parseTerm x
449+ let (eb, sb) ← getFloatEbSb α
450+ return (α, mkApp3 (.const ``abs []) (mkNatLit eb) (mkNatLit sb) x)
451+ if let sexp!{(fp.neg {x})} := e then
452+ let (α, x) ← parseTerm x
453+ let (eb, sb) ← getFloatEbSb α
454+ return (α, mkApp3 (.const ``neg []) (mkNatLit eb) (mkNatLit sb) x)
455+ if let sexp!{(fp.add {rm} {x} {y})} := e then
456+ let (_, rm) ← parseTerm rm
457+ let (α, x) ← parseTerm x
458+ let (_, y) ← parseTerm y
459+ let (eb, sb) ← getFloatEbSb α
460+ return (α, mkApp5 (.const ``add []) (mkNatLit eb) (mkNatLit sb) x y rm)
461+ if let sexp!{(fp.sub {rm} {x} {y})} := e then
462+ let (_, rm) ← parseTerm rm
463+ let (α, x) ← parseTerm x
464+ let (_, y) ← parseTerm y
465+ let (eb, sb) ← getFloatEbSb α
466+ return (α, mkApp5 (.const ``sub []) (mkNatLit eb) (mkNatLit sb) x y rm)
467+ if let sexp!{(fp.mul {rm} {x} {y})} := e then
468+ let (_, rm) ← parseTerm rm
469+ let (α, x) ← parseTerm x
470+ let (_, y) ← parseTerm y
471+ let (eb, sb) ← getFloatEbSb α
472+ return (α, mkApp5 (.const ``mul []) (mkNatLit eb) (mkNatLit sb) x y rm)
473+ if let sexp!{(fp.div {rm} {x} {y})} := e then
474+ let (_, rm) ← parseTerm rm
475+ let (α, x) ← parseTerm x
476+ let (_, y) ← parseTerm y
477+ let (eb, sb) ← getFloatEbSb α
478+ return (α, mkApp5 (.const ``div []) (mkNatLit eb) (mkNatLit sb) x y rm)
479+ if let sexp!{(fp.fma {rm} {x} {y} {z})} := e then
480+ let (_, rm) ← parseTerm rm
481+ let (α, x) ← parseTerm x
482+ let (_, y) ← parseTerm y
483+ let (_, z) ← parseTerm z
484+ let (eb, sb) ← getFloatEbSb α
485+ return (α, mkApp6 (.const ``fma []) (mkNatLit eb) (mkNatLit sb) x y z rm)
486+ if let sexp!{(fp.sqrt {rm} {x})} := e then
487+ let (_, rm) ← parseTerm rm
488+ let (α, x) ← parseTerm x
489+ let (eb, sb) ← getFloatEbSb α
490+ return (α, mkApp4 (.const ``sqrt []) (mkNatLit eb) (mkNatLit sb) x rm)
491+ if let sexp!{(fp.rem {x} {y})} := e then
492+ let (α, x) ← parseTerm x
493+ let (_, y) ← parseTerm y
494+ let (eb, sb) ← getFloatEbSb α
495+ return (α, mkApp4 (.const ``remainder []) (mkNatLit eb) (mkNatLit sb) x y)
496+ if let sexp!{(fp.roundToIntegral {rm} {x})} := e then
497+ let (_, rm) ← parseTerm rm
498+ let (α, x) ← parseTerm x
499+ let (eb, sb) ← getFloatEbSb α
500+ return (α, mkApp4 (.const ``roundToInt []) (mkNatLit eb) (mkNatLit sb) rm x)
501+ if let sexp!{(fp.min {x} {y})} := e then
502+ let (α, x) ← parseTerm x
503+ let (_, y) ← parseTerm y
504+ let (eb, sb) ← getFloatEbSb α
505+ return (α, mkApp4 (.const ``flt_min []) (mkNatLit eb) (mkNatLit sb) x y)
506+ if let sexp!{(fp.max {x} {y})} := e then
507+ let (α, x) ← parseTerm x
508+ let (_, y) ← parseTerm y
509+ let (eb, sb) ← getFloatEbSb α
510+ return (α, mkApp4 (.const ``flt_max []) (mkNatLit eb) (mkNatLit sb) x y)
511+ if let sexp!{(fp.leq {x} {y})} := e then
512+ let (α, x) ← parseTerm x
513+ let (_, y) ← parseTerm y
514+ let (eb, sb) ← getFloatEbSb α
515+ return (mkBool, mkApp4 (.const ``le []) (mkNatLit eb) (mkNatLit sb) x y)
516+ if let sexp!{(fp.lt {x} {y})} := e then
517+ let (α, x) ← parseTerm x
518+ let (_, y) ← parseTerm y
519+ let (eb, sb) ← getFloatEbSb α
520+ return (mkBool, mkApp4 (.const ``lt []) (mkNatLit eb) (mkNatLit sb) x y)
521+ if let sexp!{(fp.geq {x} {y})} := e then
522+ let (α, x) ← parseTerm x
523+ let (_, y) ← parseTerm y
524+ let (eb, sb) ← getFloatEbSb α
525+ return (mkBool, mkApp4 (.const ``ge []) (mkNatLit eb) (mkNatLit sb) x y)
526+ if let sexp!{(fp.gt {x} {y})} := e then
527+ let (α, x) ← parseTerm x
528+ let (_, y) ← parseTerm y
529+ let (eb, sb) ← getFloatEbSb α
530+ return (mkBool, mkApp4 (.const ``gt []) (mkNatLit eb) (mkNatLit sb) x y)
531+ if let sexp!{(fp.eq {x} {y})} := e then
532+ let (α, x) ← parseTerm x
533+ let (_, y) ← parseTerm y
534+ let (eb, sb) ← getFloatEbSb α
535+ return (mkBool, mkApp4 (.const ``eq []) (mkNatLit eb) (mkNatLit sb) x y)
536+ if let sexp!{(fp.isNormal {x})} := e then
537+ let (α, x) ← parseTerm x
538+ let (eb, sb) ← getFloatEbSb α
539+ return (mkBool, mkApp3 (.const ``PackedFloat.isNorm []) (mkNatLit eb) (mkNatLit sb) x)
540+ if let sexp!{(fp.isSubnormal {x})} := e then
541+ let (α, x) ← parseTerm x
542+ let (eb, sb) ← getFloatEbSb α
543+ return (mkBool, mkApp3 (.const ``PackedFloat.isSubnorm []) (mkNatLit eb) (mkNatLit sb) x)
544+ if let sexp!{(fp.isZero {x})} := e then
545+ let (α, x) ← parseTerm x
546+ let (eb, sb) ← getFloatEbSb α
547+ return (mkBool, mkApp3 (.const ``PackedFloat.isZero []) (mkNatLit eb) (mkNatLit sb) x)
548+ if let sexp!{(fp.isInfinite {x})} := e then
549+ let (α, x) ← parseTerm x
550+ let (eb, sb) ← getFloatEbSb α
551+ return (mkBool, mkApp3 (.const ``PackedFloat.isInfinite []) (mkNatLit eb) (mkNatLit sb) x)
552+ if let sexp!{(fp.isNaN {x})} := e then
553+ let (α, x) ← parseTerm x
554+ let (eb, sb) ← getFloatEbSb α
555+ return (mkBool, mkApp3 (.const ``PackedFloat.isNaN []) (mkNatLit eb) (mkNatLit sb) x)
556+ if let sexp!{(fp.isNegative {x})} := e then
557+ let (α, x) ← parseTerm x
558+ let (eb, sb) ← getFloatEbSb α
559+ return (mkBool, mkApp3 (.const ``PackedFloat.isNeg []) (mkNatLit eb) (mkNatLit sb) x)
560+ if let sexp!{(fp.isPositive {x})} := e then
561+ let (α, x) ← parseTerm x
562+ let (eb, sb) ← getFloatEbSb α
563+ return (mkBool, mkApp3 (.const ``PackedFloat.isPos []) (mkNatLit eb) (mkNatLit sb) x)
564+ if let sexp!{((_ to_fp {eb} {sb}) {x})} := e then
565+ let eb := eb.serialize.toNat!
566+ let sb := sb.serialize.toNat! - 1
567+ let (β, x) ← parseTerm x
568+ return (mkFloat eb sb, mkApp3 (.const ``PackedFloat.ofBits []) (mkNatLit eb) (mkNatLit sb) x)
354569 if let some r ← parseVar? e then
355570 return r
356571 if let some ⟨w, x⟩ := parseBVLiteral? s then
@@ -415,6 +630,7 @@ where
415630 let hα ← if α == mkBool
416631 then pure mkInstBEqBool
417632 else if α.isAppOfArity ``BitVec 1 then pure (mkInstBEqBitVec (← getBitVecWidth α))
633+ else if α.isAppOfArity ``PackedFloat 2 then let (eb, sb) ← getFloatEbSb α; pure (mkInstBEqFloat eb sb)
418634 else throw m! "Error: unsupported type for `distinct`: { α} "
419635 let mut acc : Expr := mkApp4 (.const ``bne [0 ]) α hα as0 as1
420636 for hi : i in [2 :as.length] do
0 commit comments