Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

function-arity not working #177

Open
AdrickTench opened this issue Nov 1, 2024 · 6 comments
Open

function-arity not working #177

AdrickTench opened this issue Nov 1, 2024 · 6 comments
Labels
bug Issues that represent errors in the code good first issue Good for newcomers
Milestone

Comments

@AdrickTench
Copy link
Collaborator

It appears that predicate-arity works (more or less, see #176), but function-arity does not.

metta+>(: foo (-> Number Number))
metta+>(= (foo $x) (+ $x 1))
metta+>!(predicate-arity foo)
[2]
metta+>!(function-arity foo)
[] ;; should be 1
metta+>!(predicate-arity cons-atom)
[3]
metta+>!(function-arity cons-atom)
[] ;; should be 2
@AdrickTench AdrickTench added the bug Issues that represent errors in the code label Nov 1, 2024
@TeamSPoon TeamSPoon added this to the Month 4 of 5 milestone Nov 11, 2024
@TeamSPoon
Copy link
Collaborator

good bug.. but deciding if this will be fixed from .metta or a .pl

@TeamSPoon TeamSPoon added the good first issue Good for newcomers label Nov 11, 2024
@TeamSPoon
Copy link
Collaborator

@TeamSPoon
Copy link
Collaborator

TeamSPoon commented Dec 11, 2024

Sorry so much has changed! Here is the expected behaviour which is different..

; Define that `foo` is a function that takes a Number and returns a Number.
; This sets up the type signature for `foo`.
metta+>(: foo (-> Number Number))

; Because `foo` was defined as a single-argument function returning a single value,
; querying its current function arity returns [1].
metta+>!(current-function-arity foo)
[1]

; Querying the current predicate arity of `foo` returns [2].
; As a predicate, `foo` is seen as relating an input to an output (e.g., (foo In Out)),
; thus it’s effectively a two-argument relation.
metta+>!(current-predicate-arity foo)
[2]


; Define the behavior of `bar`: (bar x) = x + 1
; This sets `bar` as another function from Number to Number.
metta+>(= (bar $x) (+ $x 1))

; Querying `bar`'s current function arity similarly returns [1], since it takes one argument.
metta+>!(current-function-arity bar)
[1]

; As a predicate, `bar` also relates an input to an output, so its predicate arity is [2].
metta+>!(current-predicate-arity bar)
[2]


; For a built-in like `cons-atom`, querying its predicate arity returns [3].
; This means as a predicate, it takes three arguments (e.g., (cons-atom Head Tail Result)).
metta+>!(current-predicate-arity cons-atom)
[3]

; Querying `cons-atom` as a function may also produce a result.
; For example, if considered as a function, it might still show [3],
; indicating how it’s currently understood in this environment.
metta+>!(current-function-arity cons-atom)
[2]


; Now consider `missing-predicate`, which we have not defined at all.
; Querying its current function or predicate arity returns [] because
; there is no information about it in the current environment.
metta+>!(current-function-arity missing-predicate)
[]
metta+>!(current-predicate-arity missing-predicate)
[]

; We can define its predicate arity by adding an atom that specifies it.
metta+>(add-atom &self (predicate-arity missing-predicate 3))

; After this, querying `missing-predicate`'s current predicate arity returns [3].
metta+>!(current-predicate-arity missing-predicate)
[3]

; Querying the persistent predicate arity (without "current") also returns [3].
metta+>!(predicate-arity missing-predicate)
[3]

; When we now query `missing-predicate`'s current function arity, it returns [2].
; This indicates that `current-function-arity` can infer or guess an arity even if
; not explicitly declared, possibly from the predicate arity or other heuristics.
metta+>!(current-function-arity missing-predicate)
[2]

; However, querying the global or persistent function arity (function-arity) returns [].
; This is because we never explicitly declared its function arity, and this query type
; doesn’t guess or infer—it only returns what was declared.
metta+>!(function-arity missing-predicate)
[]

; In other words:
; - current-*-arity queries return the best guess about the arity, possibly inferred
;   from current session definitions or rules.
; - *-arity queries (without "current") return only what has been explicitly declared
;   or persistently defined.

; Consider the following example:
(: print-two-numbers (-> Number Number))
(= (print-two-numbers $x $y) 
  (println! (x: $x y: $y)))


; Here we’ve defined `print-two-numbers` as a function with a certain type signature.
; If we query `current-function-arity print-two-numbers`, it might return [2], since
; from the definition `(print-two-numbers $x $y)`, it appears to take two arguments.
; Similarly, `current-predicate-arity print-two-numbers` might return [3],
; reflecting its interpretation as a predicate with three arguments. (which is wrong)
; so we add
(function-arity print-two-numbers 2)
(predicate-arity print-two-numbers 2)

; If we never explicitly declare `function-arity` or `predicate-arity` for it,
; the *-arity queries (without "current") return [].


Summary:

  • "current-*-arity" shows what the system currently infers or believes, based on known facts.
  • "*-arity" without "current" shows only explicitly declared or persistent definitions.
  • current-predicate-arity and current-function-arity: Provide inferred or currently known arities from the session’s context, including rules deduced on-the-fly.
  • predicate-arity and function-arity: Return only explicitly declared or persistently stored information about arities.
  • When something is not defined or declared, queries return [].
  • Once declared, persistent queries (predicate-arity, function-arity) return the declared values.
  • Inferred queries (current-predicate-arity, current-function-arity) may return a "best guess" even if nothing has been explicitly declared.

For a deeper dive .. see the comments in @https://github.com/trueagi-io/metta-wam/blob/master/prolog/metta_lang/stdlib_mettalog.metta#L100-L165

@TeamSPoon
Copy link
Collaborator

Another task is document the current-predicate-arity and current-function-arity
in the https://github.com/trueagi-io/metta-wam/blob/master/prolog/metta_lang/stdlib_mettalog.metta

@TeamSPoon
Copy link
Collaborator

@AdrickTench
Copy link
Collaborator Author

So I know variable-arity support is weird... Is it possible to define more than one arity explicitly? e.g.

(function-arity foo 1)
(function-arity foo 2)

And what about implicitly e.g.

(: foo (-> Number Number))
(: foo (-> Number Number Number))

If either is possible how do the -arity functions behave in that case? Return all values?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issues that represent errors in the code good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants