Skip to content

Commit 6fd00c2

Browse files
committed
Add initial support for FP.
1 parent 9d2639b commit 6fd00c2

8 files changed

Lines changed: 348 additions & 58 deletions

File tree

Leanwuzla.lean

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ where
111111
match expr with
112112
| .var idx => push s!"x_{idx}"
113113
| .const val =>
114-
let s := (Nat.toDigits 2 val.toNat).asString
115-
let t := (List.replicate (w - s.length) '0').asString
114+
let s := String.ofList (Nat.toDigits 2 val.toNat)
115+
let t := String.ofList (List.replicate (w - s.length) '0')
116116
let binStr := t ++ s
117117
push "#b"
118118
push binStr
@@ -384,7 +384,7 @@ where
384384
let msg ← msg.toString
385385
let pref := "solving_context::time_solve: "
386386
if msg.startsWith pref then
387-
let msg := (msg.splitOn " ")[1]!.dropRight 2
387+
let msg := (msg.splitOn " ")[1]!.dropEnd 2
388388
set <| Float.ofInt msg.toNat!
389389
parseBitwuzlaTrace children
390390
| .withContext _ msg => parseBitwuzlaTrace #[msg]

Leanwuzla/NoKernel.lean

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def runSolver (cnf : CNF Nat) (solver : System.FilePath) (lratPath : System.File
2626
return .ok lratProof
2727

2828
def decideSmtNoKernel (type : Expr) : SolverM UInt8 := do
29-
let solver ← TacticContext.new.determineSolver
29+
let solver ← determineSolver
3030
let g := (← Meta.mkFreshExprMVar type).mvarId!
3131
let (_, g) ← g.introsP
3232
trace[Meta.Tactic.bv] m!"Working on goal: {g}"
@@ -86,3 +86,15 @@ def decideSmtNoKernel (type : Expr) : SolverM UInt8 := do
8686
else
8787
logError m!"Error: {e.toMessageData}"
8888
return (1 : UInt8)
89+
where
90+
determineSolver : CoreM System.FilePath := do
91+
let opts ← getOptions
92+
let option := sat.solver.get opts
93+
if option == "" then
94+
let cadicalPath := (← IO.appPath).parent.get! / "cadical" |>.withExtension System.FilePath.exeExtension
95+
if ← cadicalPath.pathExists then
96+
return cadicalPath
97+
else
98+
return "cadical"
99+
else
100+
return option

Leanwuzla/Parser.lean

Lines changed: 269 additions & 39 deletions
Large diffs are not rendered by default.

Leanwuzla/Sexp/Dsl.lean

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ def generalIdent : Parser :=
1919
withAntiquot (mkAntiquot "generalIdent" `generalIdent) {
2020
fn := fun c s =>
2121
let startPos := s.pos
22-
let s := takeWhile1Fn (fun c => !("(){}[].".contains c) ∧ !c.isWhitespace) "expected generalized identifier" c s
23-
mkNodeToken `generalIdent startPos c s }
22+
let s := takeWhile1Fn (fun c => !("(){}⦃⦄".contains c) ∧ !c.isWhitespace) "expected generalized identifier" c s
23+
mkNodeToken `generalIdent startPos true c s }
2424

2525
def Lean.TSyntax.getGeneralId : TSyntax `generalIdent → String
2626
| ⟨.node _ `generalIdent args⟩ => args[0]!.getAtomVal
@@ -43,18 +43,18 @@ syntax "(" slist ")" : sexp
4343
syntax "{" term "}" : sexp
4444

4545
syntax sexp : slist
46-
syntax "...{" term "}" : slist
46+
syntax "" term "" : slist
4747
syntax sexp slist : slist
48-
syntax "...{" term "}" slist : slist
48+
syntax "" term "" slist : slist
4949

5050
syntax "sexp!{" sexp "}" : term
5151
syntax "slist!{" slist "}" : term
5252

5353
macro_rules
5454
| `(slist| $s:sexp) => `([sexp!{$s}])
55-
| `(slist| ...{ $t:term }) => `(($t : List Sexp))
55+
| `(slist| $t:term ) => `(($t : List Sexp))
5656
| `(slist| $s:sexp $ss:slist) => `(sexp!{$s} :: slist!{$ss})
57-
| `(slist| ...{ $t:term } $ss:slist) => `(($t : List Sexp) ++ slist!{$ss})
57+
| `(slist| $t:term $ss:slist) => `(($t : List Sexp) ++ slist!{$ss})
5858

5959
macro_rules
6060
| `(sexp| $a:generalIdent) => `(Sexp.atom $(Lean.quote a.getGeneralId))
@@ -91,13 +91,15 @@ instance : Repr Sexp where
9191
/-- info: sexp!{(foo bar)} -/
9292
#guard_msgs in #eval sexp!{({Sexp.atom "foo"} bar)}
9393
/-- info: sexp!{(foo bar)} -/
94-
#guard_msgs in #eval sexp!{(foo ...{[Sexp.atom "bar"]})}
94+
#guard_msgs in #eval sexp!{(foo [Sexp.atom "bar"])}
9595
/-- info: sexp!{(foo bar)} -/
96-
#guard_msgs in #eval sexp!{(...{[Sexp.atom "foo"]} bar)}
96+
#guard_msgs in #eval sexp!{(foo ⦃[Sexp.atom "bar"]⦄)}
9797
/-- info: sexp!{(foo bar)} -/
98-
#guard_msgs in #eval sexp!{(...{[Sexp.atom "foo"]} ...{[Sexp.atom "bar"]})}
98+
#guard_msgs in #eval sexp!{([Sexp.atom "foo"]bar)}
9999
/-- info: sexp!{(foo bar)} -/
100-
#guard_msgs in #eval sexp!{(...{[Sexp.atom "foo", Sexp.atom "bar"]})}
100+
#guard_msgs in #eval sexp!{(⦃[Sexp.atom "foo"]⦄ ⦃[Sexp.atom "bar"]⦄)}
101+
/-- info: sexp!{(foo bar)} -/
102+
#guard_msgs in #eval sexp!{(⦃[Sexp.atom "foo", Sexp.atom "bar"]⦄)}
101103
/-- info: sexp!{(foo bar)} -/
102104
#guard_msgs in #eval sexp!{{Sexp.expr [Sexp.atom "foo", Sexp.atom "bar"]}}
103105
/-- info: [] -/

Main.lean

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,37 @@ def typeCheck (e : Expr) : SolverM UInt8 := do
5858
logError m!"Error: {e.toMessageData}"
5959
return 1
6060

61+
/--
62+
Reports messages on stdout and returns the new total number of errors reported.
63+
If `json` is true, prints messages as JSON (one per line).
64+
If a message's kind is in `severityOverrides`, it will be reported with
65+
the specified severity.
66+
-/
67+
private def reportMessages (msgLog : MessageLog) (opts : Options)
68+
(json : Bool) (severityOverrides : NameMap MessageSeverity) (numErrors : Nat) : IO Nat := do
69+
let includeEndPos := Lean.Language.printMessageEndPos.get opts
70+
msgLog.unreported.foldlM (init := numErrors) fun numErrors msg => do
71+
let numErrors := numErrors + (if msg.severity matches .error then 1 else 0)
72+
let maxErrorsReached := Lean.Language.maxErrors.get opts != 0 && numErrors > Lean.Language.maxErrors.get opts
73+
let msg : Message :=
74+
if maxErrorsReached then { msg with
75+
data := s!"maximum number of errors ({Lean.Language.maxErrors.get opts}; from option `maxErrors`) reached, exiting"
76+
severity := .error
77+
} else if let some severity := severityOverrides.find? msg.kind then
78+
{msg with severity}
79+
else
80+
msg
81+
unless msg.isSilent do
82+
if json then
83+
let j ← msg.toJson
84+
IO.println j.compress
85+
else
86+
let s ← msg.toString includeEndPos
87+
IO.print s
88+
if maxErrorsReached then
89+
IO.Process.exit 1
90+
return numErrors
91+
6192
def parseAndDecideSmt2File : SolverM UInt8 := do
6293
try
6394
let goalType ← parseSmt2File (← SolverM.getInput)
@@ -71,7 +102,7 @@ def parseAndDecideSmt2File : SolverM UInt8 := do
71102
decideSmt goalType
72103
finally
73104
printTraces
74-
Lean.Language.reportMessages (← Core.getMessageLog) (← getOptions)
105+
reportMessages (← Core.getMessageLog) (← getOptions) false {} 0
75106

76107
section Cli
77108

lake-manifest.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
{"version": "1.1.0",
22
"packagesDir": ".lake/packages",
33
"packages":
4-
[{"url": "https://github.com/leanprover/lean4-cli",
4+
[{"url": "https://github.com/opencompl/fp-lean",
5+
"type": "git",
6+
"subDir": null,
7+
"scope": "",
8+
"rev": "a781e29cc715279a45f1c11022b774a09e13da5f",
9+
"name": "«fp-lean»",
10+
"manifestFile": "lake-manifest.json",
11+
"inputRev": "main",
12+
"inherited": false,
13+
"configFile": "lakefile.toml"},
14+
{"url": "https://github.com/leanprover/lean4-cli",
515
"type": "git",
616
"subDir": null,
717
"scope": "leanprover",
8-
"rev": "1604206fcd0462da9a241beeac0e2df471647435",
18+
"rev": "d9fc8ae23024be37424a189982c92356e37935c8",
919
"name": "Cli",
1020
"manifestFile": "lake-manifest.json",
11-
"inputRev": "main",
21+
"inputRev": "nightly-testing",
1222
"inherited": false,
1323
"configFile": "lakefile.toml"}],
1424
"name": "leanwuzla",

lakefile.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ supportInterpreter = true
1717
[[require]]
1818
scope = "leanprover"
1919
name = "Cli"
20+
rev = "nightly-testing"
21+
22+
[[require]]
23+
git = "https://github.com/opencompl/fp-lean"
24+
name = "fp-lean"
2025
rev = "main"

lean-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nightly-2025-06-27
1+
leanprover/lean4:nightly-2025-11-23

0 commit comments

Comments
 (0)