Does natural join distribute over set-difference? - relational-algebra

In other words, is it true that:
r1 ⋈ (r2 - r3) = r1 ⋈ r2 - r1 ⋈ r3
where r1 r2 and r3 are relations
If it isn't what is the example?

Yes.
Take a tuple t, with all attributes of the JOIN.
Let t1 be its "R1" part.
Let t2 be its "R2" part (and since R2-R3 is a valid expression, it is also the "R3" part of t).
A tuple t appears in R1 JOIN (R2 MINUS R3) if and only if :
t1 appears in R1, AND t2 appears in R2, AND t2 does not appear in R3.
A tuple t appears in (R1 JOIN R2) MINUS (R1 JOIN R3) if and only if :
t1 appears in R1, AND t2 appears in R2, and (it is not the case that) (t1 appears in R1, AND t2 appears in R3).
since t1 must appear in R1, this reduces to :
t1 appears in R1, AND t2 appears in R2, and NOT (true AND t2 appears in R3).
t1 appears in R1, AND t2 appears in R2, and NOT (t2 appears in R3).
Compare with the first case and observe that the conditions are identical.
Another way of proving the property is by observing than (R2 MINUS R3) is equivalent to (R2 INTERSECT CMP(R3)), with CMP(R3) denoting the complement of R3 (with respect to the universal relation of its type), and then applying distributivity of JOIN OVER INTERSECTION.

I don't have an answer to the question asked, but even if it's true I don't believe the equivalence is symmetrical. Consider
r1 = (a1, a2)
r2 = (a1, a2, a3)
r3 = (a2, a3)
then r1 ⋈ r2 - r1 ⋈ r3 is possible because each operand is union-compatible, while r2 - r3 is not.

Related

How to access rule data in PROLOG

I have to determine whether two rectangles overlap or not, I can do this but I am struggling with figuring out how to grab my given data, and compare it to eachother to determine larger values.
%This is :what would be happening :
%separate(rectangle(0,10,10,0), rectangle(4,6,6,4))
separate(R1,R2) :-
%I Have to figure out how to take the values from R1 and R2 and compare
%them to one another.
.
It is called "pattern matching".
separated(R1, R2) :-
R1 = rectangle(A1, B1, C1, D1),
R2 = rectangle(A2, B2, C2, D2),
/* now just use your As and Bs */
and in many cases it is better to write straight away:
separated(rectangle(A1, B1, C1, D1), rectangle(A2, B2, C2, D2)) :-
/* now just use your As and Bs */

How to make a sorting algorithm in Assembly code, in LC3

I have a simple loop that takes a name and prints the name without saving it.
looptext getc ;starts text get loop for name
;since name isn't re-used, we don't have to save it
add r1, r0, -10 ;Test for enter character
brz finishloop1 ;if enter, cancel the text loop
OUT ;If it's not enter, print out the character typed
br looptext ;Go back to loop
finishloop1
The program then asks for an ID number separated by spaces. All these values are saved into an array and each loop, it checks if the new input is the 'new' lowest value or 'new' highest value and sets it into the respectable register.
[Deleted code for copyright sake]
At the end of the code, where I need to add a sorting algorithm, I am left with an array of only characters.
I need to go through each index of the array and rearrange the characters in the numerical order (smallest to largest).
Thank you very much all of you for the tips and tricks. Thank you specifically #Ped7g for linking me that sorting algorithms page. I ended up searching around and actually finding someone on gitub that had a bubble algorithm already written out in Assembly code. So thanks for indirectly giving me the answer.
Note: For any future people coming here to find answer, here is the link the bubble sorting algorithm code:
https://github.com/oc-cs360/s2014/blob/master/lc3/bubblesort.asm. This is part of the lecture notes for a university course.
; Implementing bubble sort algorithm
; R0 File item
; R1 File item
; R2 Work variable
; R3 File pointer
; R4 Outer loop counter
; R5 Inner loop counter
.ORIG x3000
; Count the number of items to be sorted and store the value in R7
AND R2, R2, #0 ; Initialize R2 <- 0 (counter)
LD R3, FILE ; Put file pointer into R3
COUNT LDR R0, R3, #0 ; Put next file item into R0
BRZ END_COUNT ; Loop until file item is 0
ADD R3, R3, #1 ; Increment file pointer
ADD R2, R2, #1 ; Increment counter
BRNZP COUNT ; Counter loop
END_COUNT ADD R4, R2, #0 ; Store total items in R4 (outer loop count)
BRZ SORTED ; Empty file
; Do the bubble sort
OUTERLOOP ADD R4, R4, #-1 ; loop n - 1 times
BRNZ SORTED ; Looping complete, exit
ADD R5, R4, #0 ; Initialize inner loop counter to outer
LD R3, FILE ; Set file pointer to beginning of file
INNERLOOP LDR R0, R3, #0 ; Get item at file pointer
LDR R1, R3, #1 ; Get next item
NOT R2, R1 ; Negate ...
ADD R2, R2, #1 ; ... next item
ADD R2, R0, R2 ; swap = item - next item
BRNZ SWAPPED ; Don't swap if in order (item <= next item)
STR R1, R3, #0 ; Perform ...
STR R0, R3, #1 ; ... swap
SWAPPED ADD R3, R3, #1 ; Increment file pointer
ADD R5, R5, #-1 ; Decrement inner loop counter
BRP INNERLOOP ; End of inner loop
BRNZP OUTERLOOP ; End of outer loop
SORTED HALT
FILE .FILL x3500 ; File location
.END

Prolog - Checking 2x2 cells in a list of lists

Basically I am trying to implement a program in prolog that can solve a game called Yin Yang, independente of the size of the board.
The game is basically to paint every cell of the board of a specific color (either black or white) and all cells of same color are connected to each other, vertically or horizontally. I am representing this with a list of lists. Example initial->solution: https://i.gyazo.com/24a70d868934dfbf1540343e89d14c4b.png
However there is a rule I'm having trouble with: "No 2X2 group of cells can contain circles of a single color."
Any ideas how I can assure this doesn't happen using the clpfd library?
List representing board example:
[[0,0,0,0,0,0],
[0,0,0,1,0,0],
[0,0,1,1,2,0],
[0,2,0,0,2,2],
[1,0,2,0,1,0],
[0,1,0,0,0,1]]
I managed to do a variant of the problem :
get-elem(B, R, C, E) :- get-line(B, R, Row), get-line(Row, C, E).
get-line([R|_], 0, R).
get-line([_|A], N, R) :- get-line(A, M, R), N is M + 1.
twoXTwo(B, R, C) :- \+ (R1 is R+ 1, C1 is C+1,
get-elem(B, R, C, E1),
get-elem(B, R1, C, E2), E1 = E2,
get-elem(B, R, C1, E3), E2 = E3,
get-elem(B, R1, C1, E4), E3 = E4).
where I check the element at positions [(r+1,c), (r,c+1), (r+1,c+1)] are not the same element. I am also not sure what the numbers mean given you have either black (1) or white (0).
I solved the issue: This is the code I used for solving the problem described above.
twoByTwo([_],[_]).
twoByTwo([F1,S1|T1],[F2,S2|T2]):-
F1 + S1 + F2 + S2 #> 4,
F1 + S1 + F2 + S2 #< 8,
twoByTwo([S1|T1],[S2|T2]).
Basically twoByTwo receives a line of the board (in order) on each argument.
So basically this function is called recursively: twoByTwo(Line1,Line2), twoByTwo(Line2,Line3), etc.

ARM Integer Division Algorithm

I'm beginning in ARM assembly and I've been trying to write a simple integer division subroutine. So far, I have the following:
.text
start:
mov r0, #25
mov r1, #5
bl divide
b stop
divide:
cmp r0, r1
it lo
mov pc, lr
sub r0, r0, r1
add r2, r2, #1
b divide
stop:
b stop
I wrote it based on the pseudocode I came up with for the algorithm:
Is the Divisor (bottom) larger than the Dividend (top)?
Yes:
-Return the remainder and the counter(quotient)
No:
-Subtract the Divisor from the Dividend
-Increment the counter by 1
-Repeat the method
r0 contains the numerator and r1 contains the denominator.
When the algorithm finishes, r0 should contain the remainder and r2 should contain the quotient. However, upon running, r0 contains 19 and r2 contains 0.
Are there any fallacies in my logic that I'm just missing?
I removed it lo and changed mov to movlo and it worked fine.

Multiply using addition and a restricted set of instructions

I am building a CPU circuit with Logisim. My CPU has only 2 general purpose registers and a 16-byte RAM. I have encoded the following instruction set (Rxy means one of the two registers)
• ADD Rxy, Rxy (add Rxy and Rxy and store result inside the first register)
• SUB Rxy, Rxy (same but with sub)
• ST Rxy, Address (save value of Rxy into RAM address)
• LD Rxy, Address (load into Rxy value at RAM address)
• BZ Rxy, Address (branch to address if value of Rxy is zero)
I thought I could use decrement the second addend until it reaches 0 and at each step, add the first addend to itself.
For example, 5*3 = 5+5+5 ; 3-1-1-1
But I'm not sure my instruction can permit this program... I only have a branch if Rxy is equal to 0, whereas I would like to branch if not equal to 0.
My program currently looks like this :
Assume R1 is preloaded with second addends (iteration left count)
(A) LD R0, Address # constant 1
SUB R1, R0 # decrement iteration left
ST R1, Address # save iteration count in memory
LD R0, Address # Load first addend
LD R1, Address # load current total
ADD R0, R1 # do addition
ST R0, Address # save new current total
BZ R1, (B) # if iteration is 0, then display and end, else add
(B)
STOP
Is there a way to loop with my instruction set?
You can change
BZ R1, (B)
(B)
to
BZ R1, (B)
LD R0, Address # constant 1
SUB R0, R0
BZ R0, (A)
(B)

Resources