Translation to Predicate Logic with Lexicon - nlp

How would one translate the following statement into predicate logic:
"Even though the examiner hopes all students will satisfy the requirements for grade E or better, somebody will receive a lower grade and be disappointed."

The first step is to define an alphabet. Take the following first-order alphabet with the desired interpretation:
Unary predicates:
S(x): "x is a student"
E(x): "x is an examiner"
G(x): "x is a grade"
D(x): "x is disappointed"
Binary predicates:
R(x, y): "x is a requirement for y"
B(x, y): "x is y or better"
O(x, y): "x receives y"
Ternary predicates:
H(x, y, z): "x hopes that y fulfills z"
e: Constant ("the grade E")
x, y, z, w: Variables
Let's break the original statement in two parts:
S1: "The examiner hopes all students will satisfy the requirements for grade E or better"
S2: "Somebody will receive a lower grade and be disappointed"
And use the defined alphabet to write it in first-order:
S1: ∃x(E(x) ∧ ∀y(S(y) ⇒ ∃z∃w(R(z, e) ∧ B(w, z) ∧ H(x, y, w))))
S2: ∃x∃y(S(x) ∧ G(y) ∧ O(x, y) ∧ ¬B(y, e) ∧ D(x))
Finally we compute the original statement, that is:
S1 ∧ S2
Keep in mind that this is just one of the interpretations that will lead to a correct (satisfying) answer.
I hope it helps

Related

Convert DFA to RE

I constructed a finite automata for the language L of all strings made of the symbols 0, 1 and 2 (Σ = {0, 1, 2}) where the last symbol is not smaller than the first symbol. E.g., the strings 0, 2012, 01231 and 102 are in the language, but 10, 2021 and 201 are not in the language.
Then from that an GNFA so I can convert to RE.
My RE looks like this:
(0(0+1+2)* )(1(0(1+2)+1+2)* )(2((0+1)2+2))*)
I have no idea if this is correct, as I think I understand RE but not entirely sure.
Could someone please tell me if it’s correct and if not why?
There is a general method to convert any DFA into a regular expression, and is probably what you should be using to solve this homework problem.
For your attempt specifically, you can tell whether an RE is incorrect by finding a word that should be in the language, but that your RE doesn't accept, or a word that shouldn't be in the language that the RE does accept. In this case, the string 1002 should be in the language, but the RE doesn't match it.
There are two primary reasons why this string isn't matched. The first is that there should be a union rather than a concatenation between the three major parts of the language (words starting with 0, 1 and 2, respectively:
(0(0+1+2)*) (1(0(1+2)+1+2)*) (2((0+1)2+2))*) // wrong
(0(0+1+2)*) + (1(0(1+2)+1+2)*) + (2((0+1)2+2))*) // better
The second problem is that in the 1 and 2 cases, the digits smaller than the starting digit need to be repeatable:
(1(0 (1+2)+1+2)*) // wrong
(1(0*(1+2)+1+2)*) // better
If you do both of those things, the RE will be correct. I'll leave it as an exercise for you to follow that step for the 2 case.
The next thing you can try is find a way to make the RE more compact:
(1(0*(1+2)+1+2)*) // verbose
(1(0*(1+2))*) // equivalent, but more compact
This last step is just a matter of preference. You don't need the trailing +1+2 because 0* can be of zero length, so 0*(1+2) covers the +1+2 case.
You can use an algorithm but this DFA might be easy enough to convert as a one-off.
First, note that if the first symbol seen in the initial state is 0, you transition to state A and remain there. A is accepting. This means any string beginning with 0 is accepted. Thus, our regular expression might as well have a term like 0(0+1+2)* in it.
Second, note that if the first symbol seen in the initial state is 1, you transition to state B and remain in states B and D from that point on. You only leave B if you see 0 and you stay out of B as long as you keep seeing 0. The only way to end on D is if the last symbol you saw was 0. Therefore, strings beginning with 1 are accepted if and only if the strings don't end in 0. We can have a term like 1(0+1+2)*(1+2) in our regular expression as well to cover these cases.
Third, note that if the first symbol seen in the initial state is 2, you transition to state C and remain in states C and E from that point on. You leave state C if you see anything but 2 and stay out of B until you see a 2 again. The only way to end up on C is if the last symbol you saw was 2. Therefore, strings beginning with 2 are accepted if and only if the strings end in 2. We can have a term like 2(0+1+2)*(2) in our regular expression as well to cover these cases.
Finally, we see that there are no other cases to consider; our three terms cover all cases and the union of them fully describes our language:
0(0+1+2)* + 1(0+1+2)*(1+2) + 2(0+1+2)*2
It was easy to just write out the answer here because this DFA is sort of like three simple DFAs put together with a start state. More complicated DFAs might be easier to convert to REs using algorithms that don't require you understand or follow what the DFA is doing.
Note that if the start state is accepting (mentioned in a comment on another answer) the RE changes as follows:
e + 0(0+1+2)* + 1(0+1+2)*(1+2) + 2(0+1+2)*2
Basically, we just tack the empty string onto it since it is not already generated by any of the other parts of the aggregate expression.
You have the equivalent of what is known as a right-linear system. It's right-linear because the variables occur on the right hand sides only to the first degree and only on the right-hand sides of each term. The system that you have may be written - with a change in labels from 0,1,2 to u,v,w - as
S ≥ u A + v B + w C
A ≥ 1 + (u + v + w) A
B ≥ 1 + u D + (v + w) B
C ≥ 1 + (u + v) E + w C
D ≥ u D + (v + w) B
E ≥ (u + v) E + w C
The underlying algebra is known as a Kleene algebra. It is defined by the following identities that serve as its fundamental properties
(xy)z = x(yz), x1 = x = 1x,
(x + y) + z = x + (y + z), x + 0 = x = 0 + x,
y0z = 0, w(x + y)z = wxz + wyz,
x + y = y + x, x + x = x,
with a partial ordering relation defined by
x ≤ y ⇔ y ≥ x ⇔ ∃z(x + z = y) ⇔ x + y = y
With respect to this ordering relation, all finite subsets have least upper bounds, including the following
0 = ⋁ ∅, x + y = ⋁ {x, y}
The sum operator "+" is the least upper bound operator.
The system you have is a right-linear fixed point system, since it expresses the variables on the left as a (right-linear) function, as given on the right, of the variables. The object being specified by the system is the least solution with respect to the ordering; i.e. the least fixed point solution; and the regular expression sought out is the value that the main variable has in the least fixed point solution.
The last axiom(s) for Kleene algebras can be stated in any of a number of equivalent ways, including the following:
0* = 1
the least fixed point solution to x ≥ a + bx + xc is x = b* a c*.
There are other ways to express it. A consequence is that one has identities such as the following:
1 + a a* = a* = 1 + a* a
(a + b)* = a* (b a*)*
(a b)* a = a (b a)*
In general, right linear systems, such as the one corresponding to your problem may be written in vector-matrix form as 𝐪 ≥ 𝐚 + A 𝐪, with the least fixed point solution given in matrix form as 𝐪 = A* 𝐚. The central theorem of Kleene algebras is that all finite right-linear systems have least fixed point solutions; so that one can actually define matrix algebras over Kleene algebras with product and sum given respectively as matrix product and matrix sum, and that this algebra can be made into a Kleene algebra with a suitably-defined matrix star operation through which the least fixed point solution is expressed. If the matrix A decomposes into block form as
B C
D E
then the star A* of the matrix has the block form
(B + C E* D)* (B + C E* D)* C E*
(E + D B* C)* D B* (E + D B* C)*
So, what this is actually saying is that for a vector-matrix system of the form
x ≥ a + B x + C y
y ≥ b + D x + E y
the least fixed point solution is given by
x = (B + C E* D)* (a + C E* b)
y = (E + D B* C)* (D B* a + b)
The star of a matrix, if expressed directly in terms of its components, will generally be huge and highly redundant. For an n×n matrix, it has size O(n³) - cubic in n - if you allow for redundant sub-expressions to be defined by macros. Otherwise, if you in-line insert all the redundancy then I think it blows up to a highly-redundant mess that is exponential in n in size.
So, there's intelligence required and involved (literally meaning: AI) in finding or pruning optimal forms that avoid the blow-up as much as possible. That's a non-trivial job for any purported matrix solver and regular expression synthesis compiler.
An heuristic, for your system, is to solve for the variables that don't have a "1" on the right-hand side and in-line substitute the solutions - and to work from bottom-up in terms of the dependency chain of the variables. That would mean starting with D and E first
D ≥ u* (v + w) B
E ≥ (u + v)* w C
In-line substitute into the other inequations
S ≥ u A + v B + w C
A ≥ 1 + (u + v + w) A
B ≥ 1 + u u* (v + w) B + (v + w) B
C ≥ 1 + (u + v) (u + v)* w C + w C
Apply Kleene algebra identities (e.g. x x* y + y = x* y)
S ≥ u A + v B + w C
A ≥ 1 + (u + v + w) A
B ≥ 1 + u* (v + w) B
C ≥ 1 + (u + v)* w C
Solve for the next layer of dependency up: A, B and C:
A ≥ (u + v + w)*
B ≥ (u* (v + w))*
C ≥ ((u + v)* w)*
Apply some more Kleene algebra (e.g. (x* y)* = 1 + (x + y)* y) to get
B ≥ 1 + N (v + w)
C ≥ 1 + N w
where, for convenience we set N = (u + v + w)*. In-line substitute at the top-level:
S ≥ u N + v (1 + N (v + w)) + w (1 + N w).
The least fixed point solution, in the main variable S, is thus:
S = u N + v + v N (v + w) + w + w N w.
where
N = (u + v + w)*.
As you can already see, even with this simple example, there's a lot of chess-playing to navigate through the system to find an optimally-pruned solution. So, it's certainly not a trivial problem. What you're essentially doing is synthesizing a control-flow structure for a program in a structured programming language from a set of goto's ... essentially the core process of reverse-compiling from assembly language to a high level language.
One measure of optimization is that of minimizing the loop-depth - which here means minimizing the depth of the stars or the star height. For example, the expression x* (y x*)* has star-height 2 but reduces to (x + y)*, which has star height 1. Methods for reducing star-height come out of the research by Hashiguchi and his resolution of the minimal star-height problem. His proof and solution (dating, I believe, from the 1980's or 1990's) is complex and to this day the process still goes on of making something more practical of it and rendering it in more accessible form.
Hashiguchi's formulation was cast in the older 1950's and 1960's formulation, predating the axiomatization of Kleene algebras (which was in the 1990's), so to date, nobody has rewritten his solution in entirely algebraic form within the framework of Kleene algebras anywhere in the literature ... as far as I'm aware. Whoever accomplishes this will have, as a result, a core element of an intelligent regular expression synthesis compiler, but also of a reverse-compiler and programming language synthesis de-compiler. Essentially, with something like that on hand, you'd be able to read code straight from binary and the lid will be blown off the world of proprietary systems. [Bite tongue, bite tongue, mustn't reveal secret yet, must keep the ring hidden.]

How is the full adder's carry out term derived?

I'm reading the section of the full adder in Digital Design by Morris Mano and I can't seem to figure out how it got from equation A to equation B.
From a full adder's truth table and k-map using inputs x, y, and z, the carry out term, C, is defined as:
C = xy + xz + yz (equation A)
I could understand the above, but in order to leverage the xor already used by the summation term of x, y, and z, the book redefines C as:
C = z(xy' + x'y) + xy = xy'z + x'yz + xy (equation B)
How are these two equivalent? I've tried to derive one from the other on paper but I'm not able to come up with the steps in between.
Sorry my comment (which I removed) was hastily stated.
Consider the following logic table (I'm using ^ to represent XOR for brevity):
The results of xy + xz + yz are the same as xy + (x ^ y)z because, for the first 6 cases, the value of x + y and x ^ y are the same. For the last two cases where they are different, the xy term being OR'ed in is 1 which makes their difference irrelevant to the final value.

Finding if a triangle is right-angled or not

This Python 3 based function returns if a triangle is or isn't right-angled given side lengths x, y, and z. I'm having an issue simplifying the conditional statement. Should this function check for acute, right, obtuse, scalene, isosceles, and equilateral angles, or are there conditions I can skip? Any feedback is appreciated.
def right_angled(x, y, z):
"""This function returns if a triangle is or isn't
right-angled given side lengths x, y, and z."""
p = x + y + z #triangle perimeter
a_sym = p / 180 #triangle perimeter divided by 180
one = x * a_sym #angle one
two = y * a_sym #angle two
three = z * a_sym #angle three
if one and two or one and three or two and three == 90:
return "The triangle is right-angled."
elif one and two and three == 180:
return "The triangle is right-angled." #next conditional(s)?
else:
return "The triangle is not right-angled."
print(right_angled(4, 5, 6))
Your function is completely wrong.
You cannot find angle as ratio of a side and perimeter.
Expression if one and two does not calculate sum - and here is logical (boolean) operator.
To find whether rectangle is right, you can exploit Pythagorean theorem
def right_angled(a, b, c):
if (a*a+b*b==c*c) or (c*c+b*b==a*a) or (a*a+c*c==b*b) :
return "The triangle is right-angled."
else:
return "The triangle is not right-angled."
Or just return boolean result
return (a*a+b*b==c*c) or (c*c+b*b==a*a) or (a*a+c*c==b*b)
I suggest using the Pythagorean theorem to achieve this (a^2+b^2=c^2) by testing the 3 combinations of side lengths. To compensate for floating point imprecision, compare within a range:
def right_angled(a, b, c, e):
return abs(a*a+b*b-c*c)<e or abs(b*b+c*c-a*a)<e or abs(c*c+a*a-b*b)<e
However, the range depends on the scale of the side lengths, i.e., small triangles pass the test more easily than big triangles. For example, any triangle with side length ~0.01 will pass the test if e=0.01. For this reason, it is safer (but more expensive) to normalize the side lengths using the formula (a^2+b^2)/c^2=1
def right_angled(a, b, c, e):
return c>0 and abs(1-(a*a+b*b)/(c*c))<e or \
a>0 and abs(1-(b*b+c*c)/(a*a))<e or \
b>0 and abs(1-(c*c+a*a)/(b*b))<e

Determine if a sequence is an interleaving of a repetition of two strings

I have this task:
Let x be a string over some finite and fixed alphabet (think English alphabet). Given
an integer k we use x^k
to denote the string obtained by concatenating k copies of x. If x
is the string HELLO then x^3
is the string HELLOHELLOHELLO. A repetition of x is
a prefix of x^k
for some integer k. Thus HELL and HELLOHELL are both repetitions of
HELLO.
An interleaving of two strings x and y is any string that is obtained by shuffling a repetition
of x with a repetition of y. For example HELwoLOHELLrldwOH is an interleaving of
HELLO and world.
Describe an algorithm that takes three strings x, y, z as input and decides whether z is an
interleaving of x and y.
I've only come up with a solution, which has exponential complexity (We have pointer to the z word, and kind of a binary tree. In every node I have current states of possible words x and y (at the start both blank). I'm processing z, and nodes has one/two/no children depending on if the next character from z could be added to x word, y word or no word.) How could I get better than exponential complexity?
Suppose the two words x and y have length N1 and N2.
Construct a non-deterministic finite state machine with states (n1, n2) where 0 <= n1 < N1 and 0 <= n2 < N2. All states are accepting.
Transitions are:
c: (n1, n2) --> ((n1 + 1) % N1, n2) if x[n1] == c
c: (n1, n2) --> (n1, (n1 + 1) % n2) if y[n2] == c
This NDFSM recognises strings that are formed from interleaving repetitions of x and y.
Here's some ways to implement the NDFSM: https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton#Implementation
Here's a simple Python implementation.
def is_interleaved(x, y, z):
states = set([(0, 0)])
for c in z:
ns = set()
for i1, i2 in states:
if c == x[i1]:
ns.add(((i1+1)%len(x), i2))
if c == y[i2]:
ns.add((i1, (i2+1)%len(y)))
states = ns
return bool(states)
print is_interleaved('HELLO', 'world', 'HELwoLOHELLrldwOH')
print is_interleaved('HELLO', 'world', 'HELwoLOHELLrldwOHr')
print is_interleaved('aaab', 'aac', 'aaaabaacaab')
In the worst case, it'll run in O(N1 * N2 * len(z)) time and will use O(N1 * N2) space, but for many cases, the time complexity will better than this unless the strings x and y are repetitious.

How to convert (0,0) to [0,0] in prolog?

I'm making a predicate distance/3 that calculates the distance between 2 points on a 2d plane. For example :
?- distance((0,0), (3,4), X).
X = 5
Yes
My predicate only works if (0,0) is the list [0,0]. Is there a way to make this conversion?
You can do this with a simple rule that unifies its left and right sides:
convert((A,B), [A,B]).
Demo.
Although the others have answered, keep in mind that (a,b) in Prolog is actually not what you might think it is:
?- write_canonical((a,b)).
','(a,b)
true.
So this is the term ','/2. If you are working with pairs, you can do two things that are probably "prettier":
Keep them as a "pair", a-b:
?- write_canonical(a-b).
-(a,b)
true.
The advantage here is that pairs like this can be manipulated with a bunch of de-facto standard predicates, for example keysort, as well as library(pairs).
Or, if they are actually a data structure that is part of your program, you might as well make that explicit, as in coor(a, b) for example. A distance in two-dimensional space will then take two coor/2 terms:
distance(coor(X1, Y1), coor(X2, Y2), D) :-
D is sqrt((X1-X2)^2 + (Y1-Y2)^2).
If you don't know how many dimensions you have, you can then indeed keep the coordinates of each point in a list. The message here is that lists are meant for things that can have 0 or more elements in them, while pairs, or other terms with arity 2, or any term with a known arity, are more explicit about the number of elements they have.
If you just have a simple pair, you can use the univ operator and simply say something like:
X = (a,b) ,
X =.. [_|Y] .
which produces
X = (a,b) .
Y = [a,b] .
This doesn't work if X is something like (a,b,c), producing as it does
X = (a,b,c) .
Y = [a,(b,c)] .
[probably not what you want].
The more general case is pretty simple:
csv2list( X , [X] ) :- % We have a list of length 1
var(X) . % - if X is UNbound
csv2list( X , [X] ) :- % We have a list of length 1
nonvar(X) , % - if X is bound, and
X \= (_,_) . % - X is not a (_,_) term.
cs22list( Xs , [A|Ys] ) :- % otherwise (the general case) ,
nonvar(Xs) , % - if X is bound, and
Xs = (A,Bs) , % - X is a (_,) term,
csv2list(Bs,Ys % - recurse down added the first item to result list.
. % Easy!

Resources