Flora-2 diamond inheritance - prolog

Flora-2 is an eccentric language and I know this is a long shot but I haven't found any active resources devoted to it so I'm trying here. Its so popular... there is no stackoverflow tag for it. If you know anything about the status and future of Flora-2 and XSB Prolog, I'd love to hear that, too.
Can someone explain Flora-2 diamond-inheritance rules to me? The manual has an example but doesn't show the results of the example. The wording seems to be the opposite of what I see in the interpreter and in the diamond.flr demo. Here's the demo:
c[f*->g].
c1[f(a)*->a]::c.
c2[f(b)*->b]::c.
o:c1.
o:c2.
?- ?X[?Y->?Z].
(What I see happens with or without the base class c)
The manual says:
At the level of methods of arity > 1, a conflict is considered to have taken place if there are two non-overwritten definitions of the same method attached to two different superclasses. When deciding whether a conflict has taken place we disregard the arguments of the method. For instance, in
a:c. c[m(k)*->f]. a:d. d[m(u)*->f].
a multiple inheritance conflict has taken place even though in one case the method m is applied to object k, while in the other it is applied to object u.
(I'm pretty sure they mean arity >= 1 but the results are similar for arity 2 as well)
So I take that to mean that the inheritance of f has a conflict so its undefined (although I'm a bit confused about what 'undefined' means, in a related section it says "inheritance does not take place"). Here's what I get when I run the diamond:
?X = o
?Y = f
?Z = g
?X = o
?Y = f(a)
?Z = a
I expected only the first solution, although I'd think that the second solution would at least make some sense if it also had the solution
?X = o
?Y = f(b)
?Z = b
... but it didn't.
FYI, I'm using the latest stable XSB and the latest Flora-2 release... 0.95.

Stumbled upon this 2+ years after the question was asked. You should have asked it on the flora-users mailing list.
Anyway, this seems to have been a bug in that version of Flora-2. I see that the current version gives a correct answer
?X = o
?Y = f
?Z = g
That is, the two conflicting inheritances canceled each other out, as the manual describes.

I'm not familiar with Flora-2 syntax but I have a smilar example of the well-known diamond-inheritance problem in Logtalk. You can find it here:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/diamonds
See the NOTES.txt and source file comments for information on semantics, default inheritance rules, and user-overriding of default inheritance rules. You can run the example using the latest CVS version of XSB. See the SCRIPT.txt file for sample queries.

Related

Compile error using fast pipe operator after pipe last in ReasonML

The way that the "fast pipe" operator is compared to the "pipe last" in many places implies that they are drop-in replacements for each other. Want to send a value in as the last parameter to a function? Use pipe last (|>). Want to send it as the first parameter? Use fast pipe (once upon a time |., now deprecated in favour of ->).
So you'd be forgiven for thinking, as I did until earlier today, that the following code would get you the first match out of the regular expression match:
Js.String.match([%re "/(\\w+:)*(\\w+)/i"], "int:id")
|> Belt.Option.getExn
-> Array.get(1)
But you'd be wrong (again, as I was earlier today...)
Instead, the compiler emits the following warning:
We've found a bug for you!
OCaml preview 3:10-27
This has type:
'a option -> 'a
But somewhere wanted:
'b array
See this sandbox. What gives?
Looks like they screwed up the precedence of -> so that it's actually interpreted as
Js.String.match([%re "/(\\w+:)*(\\w+)/i"], "int:id")
|> (Belt.Option.getExn->Array.get(1));
With the operators inlined:
Array.get(Belt.Option.getExn, 1, Js.String.match([%re "/(\\w+:)*(\\w+)/i"], "int:id"));
or with the partial application more explicit, since Reason's syntax is a bit confusing with regards to currying:
let f = Array.get(Belt.Option.getExn, 1);
f(Js.String.match([%re "/(\\w+:)*(\\w+)/i"], "int:id"));
Replacing -> with |. works. As does replacing the |> with |..
I'd consider this a bug in Reason, but would in any case advise against using "fast pipe" at all since it invites a lot of confusion for very little benefit.
Also see this discussion on Github, which contains various workarounds. Leaving #glennsl's as the accepted answer because it describes the nature of the problem.
Update: there is also an article on Medium that goes into a lot of depth about the pros and cons of "data first" and "data last" specifically as it applies to Ocaml / Reason with Bucklescript.

Where in the V8 source does the automatic cast for BinaryOperation occour?

I stumbled again in the good old '12' + 2 = '122'
I wanted to deeply understand what happens here, so my first thesis was that
Maybe Javascript casts the right operand to the type of the first one and
then operates, like so: '12' + String(2) = '122' all good...
But no, because 12 + '2' = '122' too; So the engine's magic is clearly favoring to concat over casting to number.
My second thesis was then
Maybe the engine enumerates all operands and looks for an "operator override", similar to C#? And then favor executing that over doing the self-magic thing?
My confusion got even weirder when I realized that also '5' * '8' = 40, it casts both operands to Number and does the operation.
The only way I could possibly really understand that was to read the V8 code directly from GitHub
The farther I could track down was at v8/src/parsing/parser-base.h line 2865
// We have a "normal" binary operation.
x = factory()->NewBinaryOperation(op, x, y, pos);
if (op == Token::OR || op == Token::AND) {
impl()->RecordBinaryOperationSourceRange(x, right_range);
}
From here I got lost, because I couldn't find where this factory() is coming from.
Long story short, where does the JavaScript "type Magic" come from in the V8 Engine Source code?
V8 developer here.
There are several fast paths for various cases of addition and other operations in V8. If you want to study a canonical (slow, but complete) version, you can look for Object::Add in src/objects.cc.
That said, the source of truth here is not any given engine's implementation, but the JavaScript specification. What the + operator is supposed to do is defined here: https://tc39.github.io/ecma262/#sec-addition-operator-plus.
Any engine's implementation either does precisely that, or something that from the outside is indistinguishable from that -- otherwise it's a bug. It's not a coincidence that the implementation of Object::Add reads almost exactly like the spec ;-)

what is the differenc between these two "statments" in desciption logic

I don't know if you call this statement or not, but I have this question
what is the difference between these two statments :
A ⊑ B ⊓ C
and
A ASSERTA_SYMBOL = B ⊓ C
sorry I don't know how to write the ASSERTA_SYMBOL, but it is in this image
a real example is this:
Both expressions describe or define a concept (or class or set).
The difference is subclass vs equivalent class.
An elephant is one kind of grey, large animals. There might be other kinds.
A happy father is a man who has at least one daughter and any man with at least one daughter is a happy father. There are no others.
⊑ represents a subconcept relationship, ≐ means agreement (sometimes called the same as constructor).

Undefined predicate error in datalog

So I'm currently learning datalog. I booted it up and typed in the following:
parent(john, michael).
and was promptly given an undefined predicate error. From what I understand this should be a correct way to define a relationship in the mock database. What is wrong? I've had a hunt around the internet and can find nothing.
I'm using the Windows 64bit version of the program without the GUI
As mentioned in Datalog's answer different datalog systems have different behaviors. If you're looking for a quick-and-dirty way to learn about datalog in in general, you could also try the online interpreter for the "LogiQL" datalog variant: https://repl.logicblox.com/. (Disclosure: I work for the company that makes LogiQL.) As a hello-world you could try:
=> addblock 'parent("john", "michael").'
Succesfully added block
=> print parent
/-------------------\
| john | michael |
\-------------------/
You can find answers to these questions in the user manual of DES, which is in the folder ./doc of the distribution and can also be downloaded from its web page.
Anyway, what you have typed is a query, i.e., you are not trying to assert a new fact. If you want to interactively assert a fact, use the command /assert, as in:
DES> /assert parent(john, michael)
DES> parent(john,michael)
{
parent(john,michael)
}
Info: 1 tuple computed.
The other way to assert Datalog facts (and also rules) is to store them in a file, say parents.dl, and consult it (notice the ending dot after a fact):
Contents of parents.dl:
parent(john,michael).
End of contents of parents.dl
To consult it:
DES> /consult parents
Info: 1 rule consulted.
DES> parent(john,michael)
{
parent(john,michael)
}
Info: 1 tuple computed.
Note that the query asks the system whether the fact parent(john,michael) is deduced from its database, which it is deduced indeed. Other uses of queries include variables, as in:
DES> parent(X,Y)
{
parent(john,michael)
}
Info: 1 tuple computed.
What is the name of the datalog system that you are using? Datalog is the name of a language. Different systems accept different variants of the language. Some may require you to declare predicates before using them.

How can I use rules suggested by solve_direct? (by (rule …) doesn't always work)

Sometimes <statement> solve_direct (which I usually invoke via <statement> try) lists a number of library theorems and says “The current goal can be solved directly with: …”.
Let <theorem> be one search result of solve_direct, then in most cases I can prove <statement> by (rule theorem).
Sometimes, however, such a proof is not accepted, resulting in the error message “Failed to apply initial proof method”.
Is there a general, different technique for reusing theorems found by solve_direct?
Or does it depend on the individual situation? I could try to work out a minimal example and attach it to this question.
Personally, I just tend to just use:
apply (metis thm)
which works most of the time without forcing me to think very hard (but will still occasionally fail if tricky resolution is required).
Other methods that will also typically work include:
apply (rule thm) (* If "thm" has no premises. *)
apply (erule thm) (* If "thm" has a single premise. *)
apply (erule thm, assumption+) (* If "thm" has multiple premises. *)
Why is there no one single answer? The answer is a little complex:
Internally, solve_direct calls find_theorems solves, which then performs the following:
fun etacn thm i = Seq.take (! tac_limit) o etac thm i;
(* ... *)
if Thm.no_prems thm then rtac thm 1 goal
else (etacn thm THEN_ALL_NEW (Goal.norm_hhf_tac THEN' Method.assm_tac ctxt)) 1 goal;
This is the ML code for something similar to rule thm if there are no premises on the rule, or:
apply (erule thm, assumption+)
if there are multiple premises on the rule. As commented by Brian on your question, the above might still fail if there are complex meta-logical connectives in the assumptions (which the norm_hhf_tac deals with, but is not directly exposed as an Isabelle method as far as I am aware).
If you wanted, you could write a new method that exposes the tactic used by find_theorems directly, as follows:
ML {*
fun solve_direct_tac thm ctxt goal =
if Thm.no_prems thm then rtac thm 1 goal
else (etac thm THEN_ALL_NEW (Goal.norm_hhf_tac THEN' Method.assm_tac ctxt)) 1 goal;
*}
method_setup solve =
{* Attrib.thm >> (fn thm => fn ctxt =>
SIMPLE_METHOD' (K (solve_direct_tac thm ctxt ))) *}
"directly solve a rule"
This could then be used as follows:
lemma "⟦ a; b ⟧ ⟹ a ∧ b"
by (solve conjI)
which should hopefully solve anything solve_direct throws at you.
I found another way of using solve_direct's suggestions with by rule. When certain very basic rules from the library, such as Hilbert_Choice.someI2, are suggested, it seems that one of the facts in context actually is a rule itself, which may be applicable. The following worked for me at least in two concrete situations (source):
re-examine the “rule-like” fact, the other facts (if any) and the goal
if necessary, reorder the other facts
do the proof using <other_facts> ... by (rule <rule-like-fact>)
You can try fact or rule_tac. If I recall correctly, rule sometimes fails to apply a given rule in the presence of other facts and I am not entirely sure why; that question will have to be answered by someone who is more familiar with the implementation details of these methods than I am.

Resources