Extended BNF grammar optional [...] notation - ebnf

I read somewhere [x],y in this notation, x is optional, but I could not understand what is meant by optional. Does it means, there can be y or x,y or something else? Can anyone give some example about this?

Yes.
Documentation about []:
Optional: The items between [ and ] are optional. All or none of the items in the brackets are included.
In EBNF [] stands for optional parameters that can be ommitted, so [x],y defines the possibilities y and xy.
Example:
Bicycle_Accessories = saddle [bell | horn] {water_bottle_holders}
defines next possibilities:
saddle
saddle bell
saddle horn
saddle water_bottle_holder
saddle bell water_bottle_holder
saddle bell water_bottle_holder water_bottle_holder

Related

What answers will I get when asking this questions

I started to learn Prolog and want to solve this task. But I am not quite shure whether I am right or not. Pls, help me
pilots(A,london) = pilots(london, paris)
point(X,Y,Z) = point(X1,Y1,Z1)
letter(C) = word(letter)
noun(alpha) = alpha
'vicar' = vicar
I think that everything will give "no", but the last one will be yes. Z will be equal b, X=Z=b
Just try them in prolog.
Expression
Result
Explanation
pilots(A,london) = pilots(london,paris)
false
Variable A unifies with the atom london, but the atoms london and paris do not.
point(X,Y,Z) = point(X1,Y1,Z1)
true
The variable pairs X and X1, Y and Y1, and Z and Z1 each unify and become the same variable.
letter(C) = word(letter)
false
Although letter/1 and word/1 have the same arity, they have different functors and so do not unify.
noun(alpha) = alpha
false
The structure/term noun(alpha) with functor noun and arity 1 (noun/1) cannot unify with the atom alpha
'vicar' = vicar
true
Text delimited by single quotes (e.g., 'vicar') denotes an atom; the bare word vicar likewise denotes an atom, and, in fact, the exact, same atom as vicar: they unify (because they are identical.

How to get result from z3py calculation?

I want to use z3py to illustrate the following genealogy exercise (pa is “parent” and grpa is “grand-parent)
pa(Rob,Kev) ∧ pa(Rob,Sama) ∧ pa(Sama,Tho) ∧ pa(Dor,Jim) ∧ pa(Bor,Jim) ∧ pa(Bor,Eli) ∧ pa(Jim,Tho) ∧ pa(Sama,Samu) ∧ pa(Jim,Samu) ∧ pa(Zel,Max) ∧ pa(Samu,Max)
∀X,Y,Z pa(X,Z) ∧ pa(Z,Y) → grpa(X,Y)
The exercise consists in finding for which value of X one has the following:
∃X grpa(Rob,X) ∧ pa(X,Max)
(The answer being: for X == Samu.) I would like to rewrite this problem in z3py, so I introduce a new sort Hum (for “humans”) and write the following:
import z3
Hum = z3.DeclareSort('Hum')
pa = z3.Function('pa',Hum,Hum,z3.BoolSort())
grpa = z3.Function('grpa',Hum,Hum,z3.BoolSort())
Rob,Kev,Sama,Tho,Dor,Jim,Bor,Eli,Samu,Zel,Max = z3.Consts('Rob Kev Sama Tho Dor Jim Bor Eli Samu Zel Max', Hum)
s=z3.Solver()
for i,j in ((Rob,Kev),(Rob,Sama),(Sama,Tho),(Dor,Jim),(Bor,Jim),(Bor,Eli),(Jim,Tho),(Sama,Samu),(Jim,Samu),(Zel,Max),(Samu,Max)):
s.add(pa(i,j))
x,y,z=z3.Consts('x y z',Hum)
whi=z3.Const('whi',Hum)
s.add(z3.ForAll([x,y,z],z3.Implies(z3.And(pa(x,z),pa(z,y)),grpa(x,y))))
s.add(z3.Exists(whi,z3.And(grpa(Rob,whi),pa(whi,Max))))
The code is accepted by Python and for
print(s.check())
I get
sat
Now I know there is a solution. The problem is: how do I get the value of whi?
When I ask for print(s.model()[whi]) I get None. When I ask for s.model().evaluate(whi) I get whi, which is not very helpful.
How can I get the information that whi must be Samu for the last formula to be true?
(Auxiliary question: why is there no difference between constants and variables? I'm a bit puzzled when I define x,y,z as constants although they are variable.
Why can I not write x=Hum('x') to show that x is a variable of sort Hum?)
When you write something like:
X, Y = Const('X Y', Hum)
It does not mean that you are declaring two constants named X and Y of sort Hum. (Yes, this is indeed confusing! Especially if you're coming from a Prolog like background!)
Instead, all it means is that you are saying there are two objects X and Y, which belong to the sort Hum. It does not even mean X and Y are different. They might very well be the same, unless you explicitly state it, like this:
s.assert(z3.Distinct([X, Y]))
This might also explain your confusion regarding constants and variables. In your model, everything is a variable; you haven't declared any constants at all.
Your question about how come whi is not Samu is a little trickier to explain, but it stems from the fact that all you have are variables and no constants at all. Furthermore, whi when used as a quantified variable will never have a value in the model: If you want a value for a variable, it has to be a top-level declared variable with its own assertions. This usually trips people who are new to z3py: When you do quantification over a variable, the top-level declaration is a mere trick just to get a name in the scope, it does not actually relate to the quantified variable. If you find this to be confusing, you're not alone: It's a "hack" that perhaps ended up being more confusing than helpful to newcomers. If you're interested, this is explained in detail here: https://theory.stanford.edu/~nikolaj/programmingz3.html#sec-quantifiers-and-lambda-binding But I'd recommend just taking it on faith that the bound variable whi and what you declared at the top level as whi are just two different variables. Once you get more familiar with how z3py works, you can look into the details and reasons behind this hack.
Coming back to your modeling question: You really want these constants to be present in your model. In particular, you want to say these are the humans in my universe and nobody else, and they are all distinct. (Kind of like Prolog's closed world assumption.) This sort of thing is done with a so-called enumeration sort in z3py. Here's how I would go about modeling your problem:
from z3 import *
# Declare an enumerated sort. In this declaration we create 'Human' to be a sort with
# only the elements as we list them below. They are guaranteed to be distinct, and further
# any element of this sort is guaranteed to be equal to one of these.
Human, (Rob, Kev, Sama, Tho, Dor, Jim, Bor, Eli, Samu, Zel, Max) \
= EnumSort('Human', ('Rob', 'Kev', 'Sama', 'Tho', 'Dor', 'Jim', 'Bor', 'Eli', 'Samu', 'Zel', 'Max'))
# Uninterpreted functions for parent/grandParent relationship.
parent = Function('parent', Human, Human, BoolSort())
grandParent = Function('grandParent', Human, Human, BoolSort())
s = Solver()
# An axiom about the parent and grandParent functions. Note that the variables
# x, y, and z are merely for the quantification reasons. They don't "live" in the
# same space when you see them at the top level or within a ForAll/Exists call.
x, y, z = Consts('x y z', Human)
s.add(ForAll([x, y, z], Implies(And(parent(x, z), parent(z, y)), grandParent(x, y))))
# Express known parenting facts. Note that unlike Prolog, we have to tell z3 that
# these are the only pairs of "parent"s available.
parents = [ (Rob, Kev), (Rob, Sama), (Sama, Tho), (Dor, Jim) \
, (Bor, Jim), (Bor, Eli), (Jim, Tho), (Sama, Samu) \
, (Jim, Samu), (Zel, Max), (Samu, Max) \
]
s.add(ForAll([x, y], Implies(parent(x, y), Or([And(x==i, y == j) for (i, j) in parents]))))
# Find what makes Rob-Max belong to the grandParent relationship:
witness = Const('witness', Human)
s.add(grandParent(Rob, Max))
s.add(grandParent(Rob, witness))
s.add(parent(witness, Max))
# Let's see what witness we have:
print s.check()
m = s.model()
print m[witness]
For this, z3 says:
sat
Samu
which I believe is what you were trying to achieve.
Note that the Horn-logic of z3 can express such problems in a nicer way. For that see here: https://rise4fun.com/Z3/tutorialcontent/fixedpoints. It's an extension that z3 supports which isn't available in SMT solvers, making it more suitable for relational programming tasks.
Having said that, while it is indeed possible to express these sorts of relationships using an SMT solver, such problems are really not what SMT solvers are designed for. They are much more suitable for quantifier-free fragments of logics that involve arithmetic, bit-vectors, arrays, uninterpreted-functions, floating-point numbers, etc. It's always fun to try these sorts of problems as a learning exercise, but if this sort of problem is what you really care about, you should really stick to Prolog and its variants which are much more suited for this kind of modeling.

Prolog geometric triangle rules

Any examples on how to create rules in prolog for equilateral and isosceles triangle in 2d point?
Start with these:
equilateral(point2d(x,y), point2d(x,y), point2d(x,y))
isosceles(point2d(x,y), point2d(x,y), point2d(x,y))
To check if the triangle is equilateral, it's quite simple. To check if it is isosceles, it's a little less trivial. Here my solution:
seg_length(X1,Y1,X2,Y2,D):-
D is sqrt(((X2-X1)**2)+((Y2-Y1)**2)).
equilateral(point2d(X1,Y1), point2d(X2,Y2), point2d(X3,Y3)):-
seg_length(X1,Y1,X2,Y2,D),
seg_length(X2,Y2,X3,Y3,D),
seg_length(X3,Y3,X1,Y1,D).
isosceles(point2d(X1,Y1), point2d(X2,Y2), point2d(X3,Y3)):-
seg_length(X1,Y1,X2,Y2,D1),
seg_length(X2,Y2,X3,Y3,D2),
seg_length(X3,Y3,X1,Y1,D3),
L = [D1,D2,D3],
sort(L,LS),
length(L,LenL),
length(LS,LenLS),
LenL \== LenLS.
To check if at least two sides are equal, i use sort/2 which removes duplicates from the list. If the two lists have the same lenght, it means that all three sides are different and so the triangle is not isosceles.

can't deduce the numeral representation (church encoding) of a lambda expression λx.λy.x(xy)

I have a lambda expression: λx.λy.x(xy), and I'm supposed to infer the integer representation of it. I've read a lot about Church encodings and Church numerals specifically but I can't find what number is. Can you explain it to me in a way a 3 year old can understand or refer me to a resource better than wikipedia?
Church encoding of integers is the following:
"0" ≡ (λf.(λx.x)): Think of (λf.(λx.x)) as meaning: given a function f and an element x, the result is x: it's like applying the function f zero times to x.
"1" ≡ (λf.(λx.(fx))): Think of (λf.(λx.(fx))) as meaning: given a function f and an element x, the result is (fx): which should be thought of as apply f to x or, in more standard mathematical notation, like f(x).
"2" ≡ (λf.(λx.(f(fx)))): Think of (λf.(λx.(f(fx)))) as meaning: given a function f and an element x, the result is (f(fx)): which should be thought of as apply f to x twice or, in more standard mathematical notation, like f(f(x)).
"3" ≡ (λf.(λx.(f(f(fx))))): Think of (λf.(λx.(f(f(fx))))) as meaning: given a function f and an element x, the result is (f(f(fx))): which should be thought of as apply f to x three times or, in more standard mathematical notation, like f(f(f(x))).
I hope that you see the pattern (and the logic behind). In your case, (λx.(λy.(x(xy)))) is the Church encoding of the number 2 (using alpha-equivalence, of course).
The wikiped article is actually quite clear. What is it that you don't understand?

About Prolog syntax

Sometimes I see terms like:
X = a:b
or
X = a-b
I can do requests like
X = Y:Z
and the compiler unifies Y with a and Z with b, as expected.
Now my answer:
Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!
Maybe you can give me some links with further informations about this issue.
Thanks for your help and kind regards from Germany
Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!
What you are asking here for, is the entire operator syntax definition of Prolog. To get the very full answer to this, please refer to the tag iso-prolog for full information how to obtain the Prolog standard ISO/IEC 13211-1.
But as a short answer to start with:
Prolog syntax consists of
functional notation, like +(a,b), plus
a dynamically redefinable operator syntax, plus
some extra.
It seems you want to know which "characters" can be used as operators.
The short answer is that you can use all atoms Op that succeed for current_op(Pri,Fix,Op). So you can ask dynamically, which operators are present:
?- current_op(Pri, Fix, Op).
Pri = 1, Fix = fx, Op = ($)
; Pri = 1150, Fix = fx, Op = (module_transparent)
; Pri = 700, Fix = xfx, Op = (=#=)
; Pri = 700, Fix = xfx, Op = (#>=)
; Pri = 700, Fix = xfx, Op = (>=)
; ... .
All those operators can be used in the specified manner, as pre-, in-, or postfix with the indicated priorities. Some of these operators are specific to SWI, and some are defined by the standard. Above, only #>= and >= are standard operators.
Most of the operators consist of the graphic characters #$&*+-./:<=>?#^~ only or of letters, digits and underscores starting with a lower case letter. There are two solo characters !; and then there are ,| which are even more special. Operator names that are different to above need quoting - you rarely will encounter them.
To see how operators nest, use write_canonical(Term).
The long answer is that you are also able to define such operators yourself. However, be aware that changing the operator syntax has often many implications that are very difficult to fathom. Even more so, since many systems differ in some rarely used configurations. For example, the system you mentioned, SWI differs in several ways.
I'd suggest to avoid defining new operators until you have learned more about the Prolog language.
let's see what's inside X = Y:Z
?- display( X = Y:Z ).
=(_G3,:(_G1,_G2))
true.
then we have a nested structure, where functors are operators.
An operator is an atom, and the rule for atom syntax says that we have 3 kind to consider:
a sequence of any printable character enclosed in single quote
a sequence of special characters only, where a special character is one of `.=:-+*/><##~? (I hope I have found all of them, from this page you can check if I forgot someone !)
a sequence of lowercase/uppercase characters or the underscore, starting with a lowercase character
edit
A functor (shorthand for function constructor, I think, but function is misleading in Prolog context) it's the symbol that 'ties' several arguments. The number of arguments is named arity. In Prolog a term is an atomic literal (like a number, or an atom), or a recursive structure, composed of a functor and a number of arguments, each being a term itself (at least 1).
Given the appropriate declaration, i.e. op/3, unary and binary terms can be represented as expressions, like that one you show.
An example of operator, using the : special char, is ':-'
member(X,[X|_]).
member(X,[_|T]) :- member(X, T).
The O.P., said (and I quote):
Sometimes I see terms like: X = a:b or X = a-b
I can do requests like X = Y:Z and the compiler unifies Y with a and Z with b, as expected.
Now my answer: Which characters (or sequence of characters) am I allowed
to use to combine two Prolog atoms?!
The short answer is Pretty much whatever you want (provided it is an atom).
The longer answer is this:
What are seeing are infix (x infix_op b), prefix (pfx_op b) and suffix (b sfx_op ) operators. Any structure with an arity of 2 can be an infix operator. Any structure with an arity of 1 can be a prefix or suffix operator. As a result, any atom may be an operator.
Prolog is parsed via a precedence driven, recursive descent parser (written in Prolog, naturally). Operators are defined and enumerated, along with their precedence and associativity in the operator/3 predicate. Associativity has to do with how the parse tree is constructed. An expression like a - b - c could be parsed as ( a - ( b - c ) ) (right-associative), or ( ( a - b ) - c ) (left-associative).
Precedence has to do with how tightly operators bind. An expression like a + b * c binds as ( a + ( b * c ) not because of associativity, but because '*'/2 (multiplication) has higher precedence that '+'/2 (addition).
You can add, remove and change operators to your heart's content. Not that this gives you a lot of room to shoot yourself in the foot by breaking prolog's syntax.
It should be noted, however, that any operator expression can also be written via ordinary notation:
a + b * c
is exactly identical to
'+'( a , '*'(b,c) )

Resources