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

Representing propositions in MeTTa (existential quantifier?) #64

Open
JungeWerther opened this issue Feb 11, 2025 · 4 comments
Open

Representing propositions in MeTTa (existential quantifier?) #64

JungeWerther opened this issue Feb 11, 2025 · 4 comments
Assignees
Labels
help wanted Extra attention is needed question Further information is requested

Comments

@JungeWerther
Copy link
Collaborator

JungeWerther commented Feb 11, 2025

Let's say we have a statement "Bob has blue hair". We could represent it as a unary predicate like

(Predicate Object)
; or
(hasBlueHair Bob)

In case of a binary predicate like "Robin loves James", we can write

(Predicate Subject Object)
; or
(loves Robin James)

Universal quantification is most intuitively represented by an 'if' statement (functions are not appropriate, as discussed)
For example "all swans are black" could be represented as

(if (premise) (conclusion) ())
; or
(if (isSwan $x) (isBlack $x) ())

How would you represent the existential quantifier though? Obviously a predicate like (Exists $x) won't work. My initial thought is that it should be in a way 'dual' to the universal quantifier in the sense that A: all swans are black is equivalent to B: there does not exist a swan which is not black

So "there exists a black swan" could be "not all swans are not black"

(not (if (isSwan $x) (not (isBlack $x)) ()))

This is not equivalent to a direct assertion though, and you have to accept law of excluded middle.

As far as I'm aware you should be able to express quantified statements using dependent types in intuitionistic logic but I'm not sure how you would go about this in MeTTa.

What are your thoughts?

@JungeWerther JungeWerther added help wanted Extra attention is needed question Further information is requested labels Feb 11, 2025
@JungeWerther
Copy link
Collaborator Author

Also, about the concept of negation.

let a: A represent a proof of some proposition A.

the analogue of not A would be A => _|_ constructively, where the logical contradiction corresponds to the uninhabited/empty type.

is this the same as
(: notA (=> A empty)) ?

@JungeWerther
Copy link
Collaborator Author

Okay here's what I learned:

An existential statement (exists x: X) . A
can be formalized as a pair (a, p) with a: X and p: A[a\x] (existential quantifier introduction).

So (exists x: Swan). isBlack x can be shown by a: Swan and isBlack a.

Crucially propositions like "all swans are black" are types and not 'normal' atoms so

(: $unaryPredicate (=> Object Bool))
(: $binaryPredicate (=> Subject Object Bool))

and so on.

Quantifiers should sit at the level of functions transforming proofs into proofs, not at the level of proofs.

I'm thinking

(: existsBlackSwan (=> (Swan, (=> Swan Bool)) Bool)

then, an observation

(: blackSwan Swan)
(: isBlack (=> Swan Bool))

(blackSwan, isBlack)

would suffice to prove

!(existsBlackSwan (blackSwan, isBlack))
> [true]

@Necr0x0Der
@vsbogd

is this similar to what you had in mind?

@ngeiswei
Copy link
Collaborator

What I've been using so far is, like you suggested, to use a dependent sum for existential quantification and a dependent product for universal quantification.

An example of dependent sum in MeTTa can be found here. As for dependent product, you can merely use the arrow type -> (I can dig up an example if you want me to).

@vsbogd
Copy link
Contributor

vsbogd commented Feb 20, 2025

Representation depends on how one would like to interpret the quantifiers. Here is an example of building existential and universal quantifiers as programs which returns unit when proposition is true and empty results otherwise.

(: whiteSwan1 Swan)
(: whiteSwan2 Swan)
(: blackSwan Swan)

(isWhite whiteSwan1)
(isWhite whiteSwan2)
(isBlack blackSwan)

(: negate (-> Atom (->)))
(= (negate $expr) (
  (case $expr (
    (() Empty)
    (Empty ())
  ))))

(= (evaluate $space $predicate)
  (trace! (quote (evaluate $space $predicate))
  (case $predicate (
    ((UQ $pattern $condition) (if (== (collapse (unify $space $pattern (negate (evaluate $space $condition)) ())) ()) () Empty))
    ((EQ $pattern $condition) (if (not (== (collapse (unify $space $pattern (evaluate $space $condition) Empty)) ())) () Empty))
    ($_ (match $space $predicate ()))
  ))))

!(evaluate &self (isWhite whiteSwan1))
!(evaluate &self (UQ (: $x Swan) (isWhite $x)))
!(evaluate &self (EQ (: $x Swan) (isBlack $x)))
!(evaluate &self (EQ (: $x Swan) (isWhite $x)))

One can also represent propositions as types or have predicates as a functions which return a boolean value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants