Excluding certain property values in inline query - negation

I use the three values (=pages) A, B, C for the property is of type.
Some pages have exactly one value for is of type, some pages have all three values.
I want to #ask for pages that are of type A without being of type B and C.
I tried the following inline query:
{{#ask: [[Is of type::A]] [[Is of type::!B]] [[Is of type::!C]]}}
But it doesn’t work as intended: it lists all pages that are of type A, including those that are of type B/C in addition.

Semantic Mediawiki isn't good at subtractive queries. Your query translates in English to:
Find me every page that has all of these:
-An instance of property "Is of type" equal to A
-An instance of property "Is of type" not equal to B
-An instance of property "Is of type" not equal to C
Now here's the "gotcha": Suppose you have a page that "Is of type" A, B, and C.
-It is of type A.
-It is of a type that isn't B, namely A and C.
-It is of a type that isn't C, namely A and B.
It fits all of your conditions, and goes in the result.
I run into these types of problems often. My wiki actually has several templates for subtracting query results.

Related

Which way to store facts, apple vs exists(apple) is more idiomatic?

I am trying to develop a "simplest" prolog program.
Method 1
Conceptually, the program creates a set of facts which are stored in the database, to be queried later.
% simple facts
apple.
banana.
orange.
cherry.
The database can be queried as expected.
?- apple.
true
?- mango.
procedure `mango' does not exist
Method 2
Most textbooks which teach prolog would start such a "simplest" program using predicates, something like:
% simple facts
exists(apple).
exists(banana).
exists(orange).
exists(cherry).
The queries would then change in nature to testing whether the predicate can be satisfied, eg:
?- exists(apple).
true
?- exists(mango).
false
Question:
Is Method 1 an incorrect use of prolog? If so, why?
In my understanding, prolog is testing whether queries can be shown to be true, and to do this the database is searched. My doubt is raised by the error "procedure `mango' does not exist".
I think you are focusing on a distinction between "facts" and "predicates" which does not really exist; apple. is apple(). a predicate with no body and no arguments. The following shape:
name(argument1, argument2) :-
n2(arg3),
n3(arg4).
says that "name holds for the given arguments if n2 and n3 hold for their arguments", i.e. name only holds in certain conditions. Take the conditions away and you get:
name(argument1, argument2).
Now there are no conditions where it can fail, so it says "name holds for the given arguments". It always holds, it's like an unchanging fact, but "fact" is not a different kind of thing in Prolog, it's still a term with a functor and arity which can be called, it's just that the body of code to check is effectively true and nothing else.
Take the arguments away and you get:
name.
"name holds". It's similar to name()., no arguments.
The way Prolog is implemented, these are close to functions, procedures, subroutines in other languages - they are not the same, but Prolog looks through your code for one with a matching name (functor) and matching number of arguments (similar to method overload resolution in other languages), and calls it with the given arguments and sees whether it holds or not. If it cannot find a matching name and number of arguments, you get the "procedure does not exist" error.
In typical Prolog usage, the style name(argument1, argument2) is used so that "name" tries to describe a logical relation between the arguments, and the arguments are the data being related. e.g. length(List, Quantity) tries to explain that List is related to Quantity through the relation of length.
With method 2 you can extend it to:
exists(apple).
exists(crabapple).
exists(concrete).
food(apple).
food(crabapple).
food(snozzcumber).
edible(apple).
edible(snozzcumber).
and then ask for all things which exist, all foods, all edible things, or combinations like foods which are fictional and edible, things which exist but are inedible, etc. With method 1 you can say that apple holds, but you can't easily use it as data, can't easily query for all things which exist, can't easily change the code to describe that apple exists and is edible. With method 2 you can ask ?- exists(X). and have Prolog fill in X and tell you that apple exists. You can't easily do that with method 1.
If you put the data in place of the name (functor) that's like storing food by using an empty text file named 'apple.txt' and an empty text file named 'banana.txt' and so on, instead of putting them in a single file exists.txt. It's not a syntax or logical error to do this, if there is a reason you want to do it like that then you can, so it's hard to call it strictly "incorrect". Also like using a SQL database and making a table 'apple' and a table 'banana' and so on, instead of putting them in a table 'fruit'. Like having a bookshelf with a book named 'apple' and a book named 'banana' and so on, instead of one book named 'Fruits of the World'. You can do that, it's not incorrect to name a book "apple", but it's not a good way to use books to store lists of fruit.
If you specifically want something for codegolf where shortness trumps all other concerns then yes, fine. But it is going against the grain, against the normal use, it limits what you can do and it's not how Prolog was built to be used. It's also hard to describe something with fewer characters as "simpler" if it means a weird, limited, non-standard way of doing things.
The predicate exists/1 exists, the predicate apple/0 exists, the predicate mango/0 does not exist.
The query exists(apple). successfully reports true ("succeeds" in the Prolog vernacular), the query exists(mango). successfully reports false ("fails" to be proven, in the vernacular), the query apple. successfully reports true and the query mango. fails to execute because the predicate mango/0 does not exist.
So we can say that apple "exists", mango does not "exist", apple/0 exists, but mango/0 does not exist.
However, (in SWI Prolog),
11 ?- mango.
ERROR: toplevel: Undefined procedure: mango/0 (DWIM could not correct goal)
12 ?- [user].
:- dynamic(mango/0).
|: ^Z
true.
13 ?- mango.
false.
So you can work with your 1st method too, if you declare all the predicates of interest as dynamic.

Describe a film (entity and attribute) using the first order logic

Good morning,
I want to understand how can I describe something using the first order logic.
For example I want to describe what is a film (an entity) and what is an attribute (for example actor: Clooney) for the film. How can I describe that using the first order logic?
******* UPDATE ********
What I need to explain in first logic order is:
ENTITY: an element, an abstraction or an object that can be described with a set of properties or attributes. So I think that I must says that the entity has got a set of attributes with their respective values. An Entity describes an element, an abstraction or an object.
ATTRIBUTE: an attribute has always got a value and it always associated to an entity. It describes a specific feature/property of the entity.
DOCUMENT: a pure text description (pure text it not contains any html tags). Every document describes only ONE entity through its attribute.
To state that an object has a certain property you would use a single place predicate. For example, to state that x is a film you could write Film(x). If you want to attribute some value to an object you can use two (or more) place predicate. Using your example you could say that Clooney starred in a film as Starred(clooney, x).
There are certain conventions that people use. For example, predicates start with capital letters (Actor, Film, FatherOf) and constants start with a lower case letter (x, clooney, batman). Constants denote objects and predicates say something about the objects. In case of predicates with more than one argument the first argument is usually the subject about which you are making the statement. That way you can naturally read the logical formula as a sentence in normal language. For example, FatherOf(x, y) would read as "x is the father of y".
Answer for the update:
I am not sure whether you can do that in first order logic. You could describe an Entity as something that has certain properties by formula such as
\forall x (Entity(x) ==> Object(x) | Element(x) | Abstraction(x))
This is a bit more difficult for the Attribute. In first order logic an attribute ascribes some quality to an object or relates it to another object. You could probably use a three place predicate as in:
\forall attribute (\exists object (\exists value (Has(object, attribute, value))))
As to the document, that would be just a conjunction of such statements. For example, the description of George Clooney could be the following:
Entity(clooney) & Has(clooney, starred, gravity) & Has(clooney, bornIn, lexington) & ...
The typical way to do this is to explain that a specific object exists and this object has certain attributes. For example:
(∃x)(property1(x) & property2(x) & ~property3(x))
aka: There exists a thing that satisfies properties 1 and 2 but does not satisfy property 3.
Your current question formulation makes it unclear as to what you mean by attributes and documents. Perhaps towards your idea of attributes: it's possible to describe as the domain of property1 all the entities that satisfy it; so, for example, the domain of blue is all blue objects.
First-order logic has nothing to do with HTML -- are you trying to use HTML to represent an entity in first-order logic somehow? It remains incredibly unclear what your question is.

Which meanings of "type" are used in the standard?

In part one of the ISO standard for Prolog, ISO/IEC 13211-1:1995, the notion of "type" is used to refer to different things. This often leads to confusion.
For example, a page called IsoErrata (archived version, source) states (note that this page is not related to ISO):
7.12.2 and 8.1.2.1
There is a confusion about what a "type" is. There seem to be 3
different groups:
Those that are listed in 8.1.2.1 and also occur as ValidTypes in type_error terms in 7.12.2.b
Those that are listed in 8.1.2.1 and occur as ValidDomain in domain_error terms in 7.12.2.c
Those that are listed in 8.1.2.1 only
In addition, there are ValidDomains in 7.12.2.c that are not listed in
8.1.2.1, presumably by mistake (eg. io_mode).
8.14.3.3.f
The template requires the type atom_or_atom_list for the 3rd argument, but strangely the required error term here is
type_error(list,Operator). This results in (see examples)
op(30,xfy,0) =====> error(type_error(list,0))
where type_error(atom,0) or type_error(atom_or_atom_list,0) would be more appropriate (but note that atom_or_atom_list is not among the
ValidTypes listed in 7.12.2!). For ECLiPSe we have therefore opted for
type_error(list,Op) only if Op is an improper list, and
type_error(atom,Op) if Op is any other non-atom.
So in which meanings is "type" used, and what to do about above confusion?
There are essentially three different uses for "type" in ISO/IEC 13211-1:
Types as defined in 7.1 Types. These are: variable (7.1.1), integer (7.1.2), floating point (7.1.3), atom (7.1.4), compound term (7.1.5) and some types based on them. The next two uses will often refer to 7.1 or to terminology (3 Definitions) for its definition. What is important is that here, variables are included. This classification is motivated by Prolog's syntax:
7.1 Types
The type of any term is determined by its abstract syntax (6.1.2).
Types as defined in 7.12.2 b. These are the types that are used in type errors which are of the form type_error(ValidType, Culprit). Note that variables are now no longer included since these are either signaled as instantiation errors (7.12.2 a) or uninstantiation errors (7.12.2 k, Cor.2).
ValidType ∈ { atom, atomic, byte, callable, character, compound, evaluable, float, in_byte, in_character, integer, list, number, pair, predicate_indicator }
Types as used in the Template and modes subclause:
8.1.2.1 Type of an argument
The type of each argument is defined by one of the following atoms:
atom, atom_or_atom_list, atomic, byte, callable_term, character, character_code, character_code_list, character_list, clause, close_options_list, compound_term, evaluable, flag, head, in_byte, in_character, in_character_code, integer, io_mode, list, nonvar, number, operator_specifier, predicate_indicator, read_options_list, source_sink, stream, stream_options_list, stream_or_alias, stream_position, stream_property, term, write_options_list
Above quote mentioned only 7.12.2 and 8.1.2.1 and how they relate to each other. So this needs some more elaboration:
Types of 7.12.2 are reported with type errors. But types in 8.1.2.1 only serve in the Template and modes subclause of the definition of a built-in. They are not per se suited to be used for errors. In a concrete definition of a built-in predicate, there is a subclause x.y.z.2 Template and modes and x.y.z.3 Errors. Here are some examples of types of 8.1.2.1 (bold in the list above).
write_options_list
There is no direct one-to-one correspondence between write_options_list and the concrete types used in the errors. Instead, a type list and a domain write_option is used. So the complex type write_options_list is never signaled:
8.14.2.2 Template and modes
write_term(#stream_or_alias, #term, #write_options_list)
8.14.2.3 Errors
...
c) Options is neither a partial list nor a list
— type_error(list, Options).
...
e) An element E of the Options list is neither a
variable nor a valid write-option
— domain_error(write_option, E).
atom_or_atom_list
This is even more complex. On the one hand an atom list is expected, but also an atom is fine. So we have list and atom as relevant types:
8.14.3.2 Template and modes
op(+integer, +operator_specifier, #atom_or_atom_list)
8.14.3.3 Errors
...
f) Operator is neither a partial list nor a list nor
anatom— type_error(list, Operator).
g) An element E of the Operator list is neither avariable nor
an atom— type_error(atom, E).
It is equally plausible to produce atom for error f. On the other hand, both errors are equally applicable, and list is definitely the best for malformed lists like [a|nonlist], whereas atom is not necessarily better for 111 which might be an OCR error of [l].
callable_term
The corresponding type error contains callable. Like in
8.10.1.2 Template and modes
findall(?term, +callable_term, ?list)
8.10.1.3 Errors
...
b) Goal is neither a variable nor a callable term
— type_error(callable, Goal).
in_character_code
There is neither a corresponding type in 7.12.2 b, nor a domain in 7.12.2 c. But in 7.12.2 f it is defined for representation errors:
8.12.1.2 Template and modes
...
get_code(?in_character_code)
get_code(#stream_or_alias, ?in_character_code)
8.12.1.3 Errors
...
j) Code is an integer but not an in-character code (7.1.2.2)
— representation_error(in_character_code).
io_mode
This is listed in 8.1.2.1, contrary to the quoted text. It also appears in 7.12.2 c and is used:
8.11.5.3 Errors
...
h) Mode is an atom but not an input/output mode —
domain_error(io_mode, Mode).
character_code_list
Similar to write_options_list. However, it is erroneously mentioned in 7.12.2 c. That's an error in the standard which has been removed in Cor.3:2017.

Unrestricted variable name declaration in Mercury

I would like to declare a data type in Mercury that can have a variable number of values and names. For instance :
type goal ---> pick; give; come.
has three variables/values.
I want something like:
type myplayer ---> de value declaration here.
That's the number of variables are not restricted or fixed.
So I can use myplayer to declare values/variables like v1, v2, v3 and v4. The second time I can use it to declare something like: a, b, c, d, e, z, aa, ab and az.
The number of the values are not restricted and the names are also not fixed.
I am new in Mercury.
As others have said, this is simply impossible in Mercury - which is deliberate.
What you might want though, if you want a type that expresses: v1 v2 v3... etc is:
:- type my_type
----> v(int).
:- func name(my_type) = string.
name(v(Num)) = formst("v%d", [i(Num)]).
The type expresses v of all integers, and the function name can be used to 'pretty-print' values of this type.
What you directly ask for, simply cannot be done. Given
:- type question
---> truth(string, bool)
; blank(string, string)
; multiple(string, string, list(string)).
additional kinds of questions can only be added by extending this type where it is defined, and recompiling the module - and making a lot of other changes, too, as previously deterministic code like
answer(truth(_, yes)) = "true".
answer(truth(_, no)) = "false".
answer(blank(_, A)) = A.
answer(multiple(_, A, _)) = A.
would fail when given your new question type. Being told at compile-time where you've failed to update your program to reflect the addition of a "pick-all-the-right-answers" type of question is a good part of the reason you have a question type at all, instead of say lists of strings [["Are foxes pretty?", "true"], ["Green foxes are ____", "adorable!", "fake", "evidence of animal cruelty"]] for your question bank.
What you ask for cannot be done. However, what you actually want to do -- the end to which you thought 'variable numbers of types' would be an helpful means -- can surely be accomplished in some other way. I can't tell what way that is, as I can't tell why you wanted to do this from your question. Maybe you'd benefit from reading over discriminated unions or typeclasses in the language reference.
As far as I understand this question. You want some Prolog-like behavior. I.e without typed predicates. In statically typed system you always can achieve such behavior by handling that by yourself. A lot of time ago I saw such example in Turbo Prolog (they implemented ISO prolog in terms of Turbo/Visual Prolog).
Consider something like (I'm not sure it is correct):
:- type any_type ---> atom_value(string)
; number_value(int)
; struct_value(any_type, list(any_type)).
guess(atom_value("v1")).
guess(atom_value("a")).
guess(atom_value("aa")).
guess(number_value(42)).
guess(struct_value(atom_value("pair"), [number_value(3), number_value(4)])).

Can we peek out partially inferred typing info. from Ocaml toplevel/compiler for a program that does not compile?

I would like to know, in Ocaml, whether a partial typing info. can be drawn by some existed functionality of toplevel/compiler, for a program that does not compile? Let me explain.
In Ocaml, it's well known that inferred typed can be retrieved by -annot file. However, sometimes we have a piece of code that does not compile due to some typing error. It gives a error exported to the toplevel, of this pattern
"This expression has type A, but was expected type B"
An artificial example would be
# let x =
let y = 5 in
not y;;
Characters 32-33:
not y;;
^
Error: This expression has type int
but an expression was expected of type bool
The programmer of this piece of code should understand well the 2nd part of this message, i.e.,
"y is expected of type bool", because of the "not y" part. However, she/he might have some difficulty to understand the 1st part of this error message: how this "y" is inferred to have type "int"? Thus it would be interesting to have a partial set of inferred types, before the type conflicts are raised. For the example above, one would like the interpreter tells that the first "y" (from "let y = 5") is of type int, by which I will know the reason why the second "y" (from "not y") is infered to be of type int.
Could you tell me whether the described functionality is already provided by some ocaml interpreter/compiler?
In general words, my question is: can ocaml toplevel, or its interpreter, yield partially inferred types that user can retrieve in order to more efficiently find the source of their typing error?
This question might not make sense because of the non-uniqueness of the partially inferred type annotation. However, the example example should show that at least for some cases, and some partially inferred types have its usage.
Thank you for your ideas.
The type annotations by generated by the -annot switch are available even if the program did not compile. You'll see types for the expressions that the compiler got through, and some of them may be incomplete. This doesn't tell you the compiler's reasoning for inferring the types, but it does tell you how far the compiler went and lets you explore what it's inferred.
For example, with this source code:
let x = [(let y = 5 in not y); true];;
x has the type _a list (the compiler hasn't gotten far enough to figure out _a).
y has the type int.
not has the type bool -> bool.
The error message is that the second occurrence of y has the type int (and we've seen where it was inferred) but the context expects the type bool (and we can see that, since not is a function whose argument type is bool).
I don't know how to see these types from the toplevel, but if you have a source file with your code, you can run ocamlc -c -annot, open the source in a suitable editor (such as Emacs) and view the inferred types whether the compilation succeeded or not.

Resources