I think your reasoning in three bullets stands for open world logic.
I also had problems with negation. I had some attempts to treat everything as a closed world, i.e. if something is not defined, then it is false, but it didn't sound consistent to me. I also struggled with self-definition, as I didn't have a way to express a query that returns true if I have a proof for a formula, otherwise it returns false. I mean I had idea about a dirty hack, but it looked like a perpetuum mobile thing, totally out of harmony with the Universe.
But I managed to avoid all that story about constants true / false. I completely expelled constants from my theoretical language. First level theory manages to define the next level theory, which again may hold another level theory, and so on, even if theories at all levels are the same. And there seems to be a restriction that any level theory can't define itself in the same level (see
Tarski's undefinability theorem), assuming the theory is consistent, but it seems OK for the next level to hold anything we want, restricted by previous level.
So the road led me here: the thing is, all the formulas I care about, may be considered as stored in format: `~a \/ ~b \/ ~c \/ ... \/ u \/ v \/ w ...`. When converted to super-horn clause (hehe, what a name), negated atoms go to the conjunction on the left, and non-negated to the disjunction on the right of implication symbol. If the left side is an empty conjunction, then the left side is true. If the right side is an empty disjunction, then the right side is false. Empty conjunction and empty disjunction is the furthest I go when it comes to constants. That means I can't even store the truth on the right side (because it yields a tautology) or the falsehood on the left side (also yields tautology) of the implication.
See, this might be of your interest: I figured (
Wikipedia and co.), negation of an atom is the same as we write `atom -> false`. Now, I don't have `false` defined internally, but it could be a user defined atom as any other. So, when I enter rules for it in a form like:
( (~ 'true') -> 'false' ) /\
( (~ 'false') -> 'true' ) /\
( (@a /\ ~ @a ) -> 'false' ) /\
( (@a /\ 'true' ) -> @a ) /\
( (@a /\ 'false' ) -> 'false' ) /\
( (@a \/ ~ @a ) -> 'true' ) /\
( (@a \/ 'true' ) -> 'true' ) /\
( (@a \/ 'false' ) -> @a )
and when I run organic-mind-proving-engine, things line up neatly: if the whole formula is contradictory, alone `false` is deduced; if the whole formula is tautology, alone `true` is deduced. This user-defined mechanism persuaded me to stop chasing built-in negation, and I thought - the best thing is to avoid explicit negation when it comes to exposing it to end users. All I have are empty left side conjunctions and empty right side disjunctions for my internal interpretations - only for noting axioms and goals. Otherwise, it is up to users to introduce negation, or not, it is all about user defined theories that may or may not depend on negations. As for internal interpretation, things are getting pretty weird (see the previous post): right side empty disjunction - falsehood - is interpreted as a success, following the
proof by contradiction.
Anyway, there's a parser I'm dragging now for years which I plan to extend by left side conjunctions and right side disjunctions (had that version also, but things changed so I have to re-do it for the new version). I'm planing not to tell the computer a thing about truth / falsehood, yet to leave to the algorithm to interpret empty sides just like any other element filled sides, but in empty `for` loops, by the same code, and see what happens. If the whole thing would work OK, that would be it, I would be out of the need for constants `true` and `false`, even internally.
And to develop things further, why these two constants: true / false? why not a probability range between 0 and 1, with 0 being false and 1 being true? And why to restrict ourselves to logic, why not 3 elements fractionals like red / green / blue combinations? There should be a numerous interpretations, as there are a numerous theories about everything else but logic. Now it made sense to me to leave out binary constants like true and false out of equation: users can define whatever they want, providing specific rules to handle those constants. Thus, I opted out for no built-in constants. I exploited logic as a food for thought to form the core language in my mind, but it happens to apply to any area, not only logic, and that should work without built-in constants, if I'm not mistaken.