diff --git a/x/logic/interpreter/registry.go b/x/logic/interpreter/registry.go index 2a6eb2e9..a0d67f19 100644 --- a/x/logic/interpreter/registry.go +++ b/x/logic/interpreter/registry.go @@ -19,106 +19,108 @@ type RegistryEntry struct { cost uint64 } +const defaultCost = 1 + // Registry is a map from predicate names (in the form of "atom/arity") to predicates and their costs. var Registry = map[string]RegistryEntry{ - "call/1": {engine.Call, 1}, - "catch/3": {engine.Catch, 1}, - "throw/1": {engine.Throw, 1}, - "=/2": {engine.Unify, 1}, - "unify_with_occurs_check/2": {engine.UnifyWithOccursCheck, 1}, - "subsumes_term/2": {engine.SubsumesTerm, 1}, - "var/1": {engine.TypeVar, 1}, - "atom/1": {engine.TypeAtom, 1}, - "integer/1": {engine.TypeInteger, 1}, - "float/1": {engine.TypeFloat, 1}, - "compound/1": {engine.TypeCompound, 1}, - "acyclic_term/1": {engine.AcyclicTerm, 1}, - "compare/3": {engine.Compare, 1}, - "sort/2": {engine.Sort, 1}, - "keysort/2": {engine.KeySort, 1}, - "functor/3": {engine.Functor, 1}, - "arg/3": {engine.Arg, 1}, - "=../2": {engine.Univ, 1}, - "copy_term/2": {engine.CopyTerm, 1}, - "term_variables/2": {engine.TermVariables, 1}, - "is/2": {engine.Is, 1}, - "=:=/2": {engine.Equal, 1}, - "=\\=/2": {engine.NotEqual, 1}, - "/2": {engine.GreaterThan, 1}, - ">=/2": {engine.GreaterThanOrEqual, 1}, - "clause/2": {engine.Clause, 1}, - "current_predicate/1": {engine.CurrentPredicate, 1}, - "asserta/1": {engine.Asserta, 1}, - "assertz/1": {engine.Assertz, 1}, - "retract/1": {engine.Retract, 1}, - "abolish/1": {engine.Abolish, 1}, - "findall/3": {engine.FindAll, 1}, - "bagof/3": {engine.BagOf, 1}, - "setof/3": {engine.SetOf, 1}, - "current_input/1": {engine.CurrentInput, 1}, - "current_output/1": {engine.CurrentOutput, 1}, - "set_input/1": {engine.SetInput, 1}, - "set_output/1": {engine.SetOutput, 1}, - "open/4": {engine.Open, 1}, - "close/2": {engine.Close, 1}, - "flush_output/1": {engine.FlushOutput, 1}, - "stream_property/2": {engine.StreamProperty, 1}, - "set_stream_position/2": {engine.SetStreamPosition, 1}, - "get_char/2": {engine.GetChar, 1}, - "peek_char/2": {engine.PeekChar, 1}, - "put_char/2": {engine.PutChar, 1}, - "get_byte/2": {engine.GetByte, 1}, - "peek_byte/2": {engine.PeekByte, 1}, - "put_byte/2": {engine.PutByte, 1}, - "read_term/3": {engine.ReadTerm, 1}, - "write_term/3": {engine.WriteTerm, 1}, - "op/3": {engine.Op, 1}, - "current_op/3": {engine.CurrentOp, 1}, - "char_conversion/2": {engine.CharConversion, 1}, - "current_char_conversion/2": {engine.CurrentCharConversion, 1}, - `\+/1`: {engine.Negate, 1}, - "repeat/0": {engine.Repeat, 1}, - "call/2": {engine.Call1, 1}, - "call/3": {engine.Call2, 1}, - "call/4": {engine.Call3, 1}, - "call/5": {engine.Call4, 1}, - "call/6": {engine.Call5, 1}, - "call/7": {engine.Call6, 1}, - "call/8": {engine.Call7, 1}, - "atom_length/2": {engine.AtomLength, 1}, - "atom_concat/3": {engine.AtomConcat, 1}, - "sub_atom/5": {engine.SubAtom, 1}, - "atom_chars/2": {engine.AtomChars, 1}, - "atom_codes/2": {engine.AtomCodes, 1}, - "char_code/2": {engine.CharCode, 1}, - "number_chars/2": {engine.NumberChars, 1}, - "number_codes/2": {engine.NumberCodes, 1}, - "set_prolog_flag/2": {engine.SetPrologFlag, 1}, - "current_prolog_flag/2": {engine.CurrentPrologFlag, 1}, - "halt/1": {engine.Halt, 1}, - "consult/1": {engine.Consult, 1}, - "phrase/3": {engine.Phrase, 1}, - "expand_term/2": {engine.ExpandTerm, 1}, - "append/3": {engine.Append, 1}, - "length/2": {engine.Length, 1}, - "between/3": {engine.Between, 1}, - "succ/2": {engine.Succ, 1}, - "nth0/3": {engine.Nth0, 1}, - "nth1/3": {engine.Nth1, 1}, - "call_nth/2": {engine.CallNth, 1}, - "chain_id/1": {predicate.ChainID, 1}, - "block_height/1": {predicate.BlockHeight, 1}, - "block_time/1": {predicate.BlockTime, 1}, - "bank_balances/2": {predicate.BankBalances, 1}, - "bank_spendable_balances/2": {predicate.BankSpendableBalances, 1}, - "bank_locked_balances/2": {predicate.BankLockedBalances, 1}, - "did_components/2": {predicate.DIDComponents, 1}, - "sha_hash/2": {predicate.SHAHash, 1}, - "hex_bytes/2": {predicate.HexBytes, 1}, - "bech32_address/2": {predicate.Bech32Address, 1}, - "source_file/1": {predicate.SourceFile, 1}, + "call/1": {engine.Call, defaultCost}, + "catch/3": {engine.Catch, defaultCost}, + "throw/1": {engine.Throw, defaultCost}, + "=/2": {engine.Unify, defaultCost}, + "unify_with_occurs_check/2": {engine.UnifyWithOccursCheck, defaultCost}, + "subsumes_term/2": {engine.SubsumesTerm, defaultCost}, + "var/1": {engine.TypeVar, defaultCost}, + "atom/1": {engine.TypeAtom, defaultCost}, + "integer/1": {engine.TypeInteger, defaultCost}, + "float/1": {engine.TypeFloat, defaultCost}, + "compound/1": {engine.TypeCompound, defaultCost}, + "acyclic_term/1": {engine.AcyclicTerm, defaultCost}, + "compare/3": {engine.Compare, defaultCost}, + "sort/2": {engine.Sort, defaultCost}, + "keysort/2": {engine.KeySort, defaultCost}, + "functor/3": {engine.Functor, defaultCost}, + "arg/3": {engine.Arg, defaultCost}, + "=../2": {engine.Univ, defaultCost}, + "copy_term/2": {engine.CopyTerm, defaultCost}, + "term_variables/2": {engine.TermVariables, defaultCost}, + "is/2": {engine.Is, defaultCost}, + "=:=/2": {engine.Equal, defaultCost}, + "=\\=/2": {engine.NotEqual, defaultCost}, + "/2": {engine.GreaterThan, defaultCost}, + ">=/2": {engine.GreaterThanOrEqual, defaultCost}, + "clause/2": {engine.Clause, defaultCost}, + "current_predicate/1": {engine.CurrentPredicate, defaultCost}, + "asserta/1": {engine.Asserta, defaultCost}, + "assertz/1": {engine.Assertz, defaultCost}, + "retract/1": {engine.Retract, defaultCost}, + "abolish/1": {engine.Abolish, defaultCost}, + "findall/3": {engine.FindAll, defaultCost}, + "bagof/3": {engine.BagOf, defaultCost}, + "setof/3": {engine.SetOf, defaultCost}, + "current_input/1": {engine.CurrentInput, defaultCost}, + "current_output/1": {engine.CurrentOutput, defaultCost}, + "set_input/1": {engine.SetInput, defaultCost}, + "set_output/1": {engine.SetOutput, defaultCost}, + "open/4": {engine.Open, defaultCost}, + "close/2": {engine.Close, defaultCost}, + "flush_output/1": {engine.FlushOutput, defaultCost}, + "stream_property/2": {engine.StreamProperty, defaultCost}, + "set_stream_position/2": {engine.SetStreamPosition, defaultCost}, + "get_char/2": {engine.GetChar, defaultCost}, + "peek_char/2": {engine.PeekChar, defaultCost}, + "put_char/2": {engine.PutChar, defaultCost}, + "get_byte/2": {engine.GetByte, defaultCost}, + "peek_byte/2": {engine.PeekByte, defaultCost}, + "put_byte/2": {engine.PutByte, defaultCost}, + "read_term/3": {engine.ReadTerm, defaultCost}, + "write_term/3": {engine.WriteTerm, defaultCost}, + "op/3": {engine.Op, defaultCost}, + "current_op/3": {engine.CurrentOp, defaultCost}, + "char_conversion/2": {engine.CharConversion, defaultCost}, + "current_char_conversion/2": {engine.CurrentCharConversion, defaultCost}, + `\+/1`: {engine.Negate, defaultCost}, + "repeat/0": {engine.Repeat, defaultCost}, + "call/2": {engine.Call1, defaultCost}, + "call/3": {engine.Call2, defaultCost}, + "call/4": {engine.Call3, defaultCost}, + "call/5": {engine.Call4, defaultCost}, + "call/6": {engine.Call5, defaultCost}, + "call/7": {engine.Call6, defaultCost}, + "call/8": {engine.Call7, defaultCost}, + "atom_length/2": {engine.AtomLength, defaultCost}, + "atom_concat/3": {engine.AtomConcat, defaultCost}, + "sub_atom/5": {engine.SubAtom, defaultCost}, + "atom_chars/2": {engine.AtomChars, defaultCost}, + "atom_codes/2": {engine.AtomCodes, defaultCost}, + "char_code/2": {engine.CharCode, defaultCost}, + "number_chars/2": {engine.NumberChars, defaultCost}, + "number_codes/2": {engine.NumberCodes, defaultCost}, + "set_prolog_flag/2": {engine.SetPrologFlag, defaultCost}, + "current_prolog_flag/2": {engine.CurrentPrologFlag, defaultCost}, + "halt/1": {engine.Halt, defaultCost}, + "consult/1": {engine.Consult, defaultCost}, + "phrase/3": {engine.Phrase, defaultCost}, + "expand_term/2": {engine.ExpandTerm, defaultCost}, + "append/3": {engine.Append, defaultCost}, + "length/2": {engine.Length, defaultCost}, + "between/3": {engine.Between, defaultCost}, + "succ/2": {engine.Succ, defaultCost}, + "nth0/3": {engine.Nth0, defaultCost}, + "nth1/3": {engine.Nth1, defaultCost}, + "call_nth/2": {engine.CallNth, defaultCost}, + "chain_id/1": {predicate.ChainID, defaultCost}, + "block_height/1": {predicate.BlockHeight, defaultCost}, + "block_time/1": {predicate.BlockTime, defaultCost}, + "bank_balances/2": {predicate.BankBalances, defaultCost}, + "bank_spendable_balances/2": {predicate.BankSpendableBalances, defaultCost}, + "bank_locked_balances/2": {predicate.BankLockedBalances, defaultCost}, + "did_components/2": {predicate.DIDComponents, defaultCost}, + "sha_hash/2": {predicate.SHAHash, defaultCost}, + "hex_bytes/2": {predicate.HexBytes, defaultCost}, + "bech32_address/2": {predicate.Bech32Address, defaultCost}, + "source_file/1": {predicate.SourceFile, defaultCost}, } // RegistryNames is the list of the predicate names in the Registry. diff --git a/x/logic/keeper/interpreter.go b/x/logic/keeper/interpreter.go index e8369775..d433c70f 100644 --- a/x/logic/keeper/interpreter.go +++ b/x/logic/keeper/interpreter.go @@ -11,6 +11,7 @@ import ( "github.com/ichiban/prolog" "github.com/okp4/okp4d/x/logic/interpreter" "github.com/okp4/okp4d/x/logic/interpreter/bootstrap" + "github.com/okp4/okp4d/x/logic/meter" "github.com/okp4/okp4d/x/logic/types" "github.com/okp4/okp4d/x/logic/util" u "github.com/rjNemo/underscore" @@ -96,14 +97,16 @@ func (k Keeper) newInterpreter(ctx goctx.Context) (*prolog.Interpreter, error) { params := k.GetParams(sdkctx) interpreterParams := params.GetInterpreter() + gasPolicy := params.GetGasPolicy() whitelist := util.NonZeroOrDefault(interpreterParams.PredicatesWhitelist, interpreter.RegistryNames) blacklist := interpreterParams.GetPredicatesBlacklist() + gasMeter := meter.WithWeightedMeter(sdkctx.GasMeter(), gasPolicy.WeightingFactor.Uint64()) interpreted, err := interpreter.New( ctx, filterPredicates(interpreter.RegistryNames, whitelist, blacklist), util.NonZeroOrDefault(interpreterParams.GetBootstrap(), bootstrap.Bootstrap()), - sdkctx.GasMeter(), + gasMeter, k.fsProvider(ctx), )