@@ -6,7 +6,7 @@ use powdr_ast::{
66 analyzed:: { PolyID , PolynomialType } ,
77 indent,
88} ;
9- use powdr_jit_compiler:: util_code:: util_code;
9+ use powdr_jit_compiler:: { util_code:: util_code, CodeGenerator , DefinitionFetcher } ;
1010use powdr_number:: FieldElement ;
1111
1212use crate :: witgen:: {
@@ -23,6 +23,7 @@ use crate::witgen::{
2323
2424use super :: {
2525 effect:: { Assertion , BranchCondition , Effect , ProverFunctionCall } ,
26+ prover_function_heuristics:: ProverFunction ,
2627 symbolic_expression:: { BinaryOperator , BitOperator , SymbolicExpression , UnaryOperator } ,
2728 variable:: Variable ,
2829} ;
@@ -87,17 +88,28 @@ extern "C" fn call_machine<T: FieldElement, Q: QueryCallback<T>>(
8788}
8889
8990/// Compile the given inferred effects into machine code and load it.
90- pub fn compile_effects < T : FieldElement > (
91+ pub fn compile_effects < T : FieldElement , D : DefinitionFetcher > (
92+ definitions : & D ,
9193 column_layout : ColumnLayout ,
9294 known_inputs : & [ Variable ] ,
9395 effects : & [ Effect < T , Variable > ] ,
96+ prover_functions : Vec < ProverFunction < T > > ,
9497) -> Result < WitgenFunction < T > , String > {
9598 let utils = util_code :: < T > ( ) ?;
9699 let interface = interface_code ( column_layout) ;
100+ let mut codegen = CodeGenerator :: new ( definitions) ;
101+ let prover_functions = prover_functions
102+ . iter ( )
103+ . map ( |f| prover_function_code ( f, & mut codegen) )
104+ . collect :: < Result < Vec < _ > , _ > > ( ) ?
105+ . into_iter ( )
106+ . format ( "\n " ) ;
97107 let witgen_code = witgen_code ( known_inputs, effects) ;
98108 let code = format ! (
99109 "{utils}\n \
100110 //-------------------------------\n \
111+ {prover_functions}\n \
112+ //-------------------------------\n \
101113 {interface}\n \
102114 //-------------------------------\n \
103115 {witgen_code}"
@@ -522,11 +534,31 @@ fn interface_code(column_layout: ColumnLayout) -> String {
522534 )
523535}
524536
537+ fn prover_function_code < T : FieldElement , D : DefinitionFetcher > (
538+ f : & ProverFunction < ' _ , T > ,
539+ codegen : & mut CodeGenerator < ' _ , T , D > ,
540+ ) -> Result < String , String > {
541+ let ProverFunction :: ComputeFrom ( f) = f else {
542+ return Err ( "ProvideIfUnknown functions are not supported" . to_string ( ) ) ;
543+ } ;
544+
545+ let code = codegen. generate_code_for_expresson ( f. computation ) ?;
546+
547+ let index = f. index ;
548+ Ok ( format ! (
549+ "fn prover_function_{index}(i: u64, args: &[FieldElement]) -> FieldElement {{\n \
550+ let i: ibig::IBig = i.into();\n \
551+ ({code}).call(args.to_vec().into())\n \
552+ }}"
553+ ) )
554+ }
555+
525556#[ cfg( test) ]
526557mod tests {
527558
528559 use std:: ptr:: null;
529560
561+ use powdr_ast:: analyzed:: FunctionValueDefinition ;
530562 use pretty_assertions:: assert_eq;
531563 use test_log:: test;
532564
@@ -538,18 +570,27 @@ mod tests {
538570
539571 use super :: * ;
540572
573+ struct NoDefinitions ;
574+ impl DefinitionFetcher for NoDefinitions {
575+ fn get_definition ( & self , _: & str ) -> Option < & FunctionValueDefinition > {
576+ None
577+ }
578+ }
579+
541580 fn compile_effects (
542581 column_count : usize ,
543582 known_inputs : & [ Variable ] ,
544583 effects : & [ Effect < GoldilocksField , Variable > ] ,
545584 ) -> Result < WitgenFunction < GoldilocksField > , String > {
546585 super :: compile_effects (
586+ & NoDefinitions ,
547587 ColumnLayout {
548588 column_count,
549589 first_column_id : 0 ,
550590 } ,
551591 known_inputs,
552592 effects,
593+ vec ! [ ] ,
553594 )
554595 }
555596
0 commit comments