Zulip Chat Archive
Stream: lean4
Topic: Using result from foreign function in a tactic
Ramon Fernandez Mir (Aug 31 2021 at 14:23):
I've been playing around with the extern command and I was wondering how to use a foreign function in a tactic. Say that I have a C++ function that returns 5, and I want a tactic that tries to close the goal with 5. I've followed https://github.com/leanprover/lean4/tree/master/tests/compiler/foreign to write the Makefile and the C++ code. Here's what I have so far:
/* MyFunction.cpp */
#include <lean/object.h>
#include <lean/io.h>
extern "C" lean_object * my_function(lean_object /* w */) {
return lean_io_result_mk_ok(lean_int_to_int(5));
}
-- MyFunction.lean
import Lean.Elab.Tactic.Basic
@[extern "my_function"]
constant myFunction : IO Int
open Lean Meta Elab Tactic
syntax (name := Lean.Parser.Tactic.five) "five" : tactic
@[tactic five] def five : Tactic := fun stx => do
let x ← myFunction
assignExprMVar (← getMainGoal).1 (toExpr x.toNat)
let (mvarId :: mvarIds') ← getGoals | throwError "Error"
modify fun s => { s with goals := mvarIds' }
--def myFive : Nat := by five
--#eval myFive
def main : IO Unit := do
let x ← myFunction
IO.println x
If I leanmake
it as it is, it works fine and prints 5 as expected, however as soon as I try to use this five
tactic, I get could not find native implementation of external declaration 'myFunction'
.
I've tried to split the code in different ways and tried to package the tactic as a plugin and then link it but with no success. What is the right way to make the implementation of myFunction
visible to the tactic?
Mac (Sep 01 2021 at 23:53):
@Ramon Fernandez Mir In order to use foreign functions in interpreted contexts (e.g., files run directly with the lean
binary; editing in the editor, interactive theorem proving, etc.) you need to build your library with -shared
and pass it to lean
as a plugin (with --plugin path/to/built/shared/library.[dll|so]
). To provide such a plugin to the lean
server that an VSCode uses you will need a new version of the extension that allows you pass the --plugin
argument to server. This feature is already in the master
branch (disclaimer: I was the one who added it), but you will need to wait until @Gabriel Ebner releases a new version to get it by the ordinary distribution channels.
Ramon Fernandez Mir (Sep 03 2021 at 10:28):
I see. What about simply using the plugin from lean --run
? I thought that creating the shared object like this leanc -shared -x none build/cpp/MyFunction.o -o build/cpp/MyFunction.so
and then running lean --run FileUsingMyFunction.lean --plugin=build/cpp/MyFunction.so
would do the trick. But I get the following error :.../MyFunction.so does not seem to contain a module 'MyFunction.Default'
. What does that mean?
Last updated: Dec 20 2023 at 11:08 UTC