EDIT: I am close to finishing. Here is my code so far. All I need to do is figure out how to make the code to do the last step...

EDIT2: The last step got subdivided into about 3 steps and I'm finishing up the last part of the first step now. Also made some design changes.

EDIT3: Tired. So tired..

EDIT4: So very close. Need to figure out just one last bit of code.

'Alright, so here is something that solves this specific problem, with 5 attributes and 5 men.

'Before making the program, I want to have "clean" data.

'First, let's transform the sentences into easy to parse logic. Before that, let's define the

'variables.

DECLARE SUB setNonAdjacentValuesToZero (matrix() AS BYTE, matrixloc() AS BYTE, i, j1, j2, position as BYTE)

DECLARE SUB qsort.linked.string.lowstart (array1() AS STRING, array2() AS INTEGER, amax AS INTEGER)

DECLARE FUNCTION findValue(ats() AS STRING, vtf AS STRING, a AS INTEGER, b AS INTEGER) AS INTEGER

DEFINT A-Z

DIM testarray1(0 TO 10)

DIM shared attrib = 6

DIM shared attribpos = 5

DIM attribString$(0 TO attrib-1)

attribString$(0) = "brit, swede, dane, norwegian, german"

attribString$(1) = "red, green, yellow, white, blue"

attribString$(2) = "dogs, cats, horses, birds, fish"

attribString$(3) = "water, beer, tea, coffee, milk"

attribString$(4) = "pall mall, blends, dunhill, prince, blue master"

attribString$(5) = "leftmost, 2nd, center, 4th, rightmost"

DIM totAttrib: totAttrib = attrib*attribpos

DIM matrixAttrib$(0 TO totAttrib-1), matrixAttrib2$(0 TO totAttrib-1)

DIM linksTo(0 TO totAttrib-1)

DIM tempAttrib$(0 TO 1)

DIM matrix(0 TO attrib-1, 0 TO attribpos-1, 0 TO attrib-1, 0 TO attribpos-1) AS byte

for i = 0 to attrib-1

for j = 0 to attribpos-1

for k = 0 to attrib-1

for m = 0 to attribpos-1

matrix(i, j, k, m) = 1

next m, k, j, i

DIM matrixSolution(0 TO attrib-1, 0 TO attribpos-1) AS BYTE

DIM logicAmount = 15

DIM matrixloc(1 to logicAmount-1, 0 TO 6) AS BYTE, locpos

DIM val1(0 TO 1), val2(0 to 1)

DIM logic$(0 to logicAmount-1)

logic$(0) = "brit = red" '"The brit lives in the red house"

logic$(1) = "swede = dogs"

logic$(2) = "dane = tea" 'spatial strings must be

logic$(3) = "green = left of white" 'on the right side.

logic$(4) = "green = coffee"

logic$(5) = "pall mall = birds"

logic$(6) = "yellow = dunhill"

logic$(7) = "center = milk"

logic$(8) = "leftmost = norwegian"

logic$(9) = "blends = next to cats"

logic$(10) = "horses = next to dunhill"

logic$(11) = "blue master = beer"

logic$(12) = "german = prince"

logic$(13) = "norwegian = next to blue"

logic$(14) = "blends = next to water"

'Now we transform the sentences into the matrix.

'Matrix starts by default having all 1's.

'values of matrix():

'0 = false

'1 = true

'

'As an example, take:

'matrix(0, 0, 1, 1) = 1 [0 = nationality, next 0 = brit, 1 = color, next value = color type] = true/false/unknown

'matrix(0, 0, 1, 1) = 1

'matrix(0, 0, 1, 2) = 0

'matrix(0, 0, 1, 3) = 0

'matrix(0, 0, 1, 4) = 0

'This means that the brit has either a red house or a green house.

'matrix(0, 0, 1, 0) = 0

'matrix(0, 0, 1, 1) = 1

'matrix(0, 0, 1, 2) = 1

'matrix(0, 0, 1, 3) = 1

'matrix(0, 0, 1, 4) = 1

'This means that the brit lives next to someone with a red house,

'or in other words, the brit definitely does not have a red house.

'we also must temporarily add that SOMEONE next to the Brit has

'a red house.

'matrixloc(n, 0) = 0 'nationality

'matrixloc(n, 1) = 0 'brit

'matrixloc(n, 2) = 1 'house

'matrixloc(n, 3) = 1 'red

'matrixloc(n, 4) = 2 'next to

'n = n + 1

'If we know, at some point in the future, the position of the brit,

'we can limit the color of non-nearby houses to exclude red:

'Let's say the brit is in the center house:

'

'matrix(5, 1, 1, 0) = 0 [5 = house, 2 = 2nd house, 1 = color, next value = color type]

'matrix(5, 1, 1, 1) = 1

'matrix(5, 1, 1, 2) = 1

'matrix(5, 1, 1, 3) = 1

'matrix(5, 1, 1, 4) = 1

'matrix(5, 5, 1, 0) = 0 [the 2nd house]

'matrix(5, 5, 1, 1) = 1

'matrix(5, 5, 1, 2) = 1

'matrix(5, 5, 1, 3) = 1

'matrix(5, 5, 1, 4) = 1

'Let's parse AttribString$ into matrixAttrib$().

k=0

FOR i = 0 TO attrib-1

startLoc = 1

FOR j = 0 TO attribpos-1

IF j < attrib-1 THEN

endLoc = INSTR(startLoc, attribString$(i), ",")

ELSE

endLoc = LEN(attribString$(i)) + 1

END IF

matrixAttrib$(k) = LCASE$(LTRIM$(RTRIM$(MID$(attribString$(i), startLoc, endLoc-startLoc))))

matrixAttrib2$(k) = matrixAttrib$(k)

k = k + 1

startLoc = endLoc + 1

NEXT j, i

'To parse the logic sentences, we need a function that gives the

'attribute type [i] (e.g. house) and attribute position [j] (e.g. red)

'from the name of the attribute.

'Each attribute name corresponds to a value 0 through attrib^2-1,

'which become i = (value \ attribpos) and j = value - i * attribpos.

'We can use a B-tree to find the value given a sorted list.

'So, we must sort a duplicate of matrixAttrib$(k) along with a value link LinksTo.

for i = 0 to totAttrib-1: LinksTo(i) = i: next i

qsort.linked.string.lowstart matrixAttrib2$(), LinksTo(), totAttrib-1

'The structure of the sentence is:

'{spatial string set} [attribute name] = {spatial string set} [another attribute name]

'{spatial string set} = {"left of", "right of", "next to"}

'Let's parse the sentences now...

FOR i = 0 to logicAmount-1

'First, separate each word or phrase into two parts:

startLoc = 1

endLoc = INSTR(startLoc, logic$(i), "=")

tempAttrib$(0) = LCASE$(LTRIM$(RTRIM$(MID$(logic$(i), startLoc, endLoc-startLoc))))

tempAttrib$(1) = LCASE$(LTRIM$(RTRIM$(MID$(logic$(i), endLoc+1))))

testLeft = INSTR(tempAttrib$(1), "left of")

If testLeft THEN pos1 = 1: tempAttrib$(1) = LCASE$(LTRIM$(RTRIM$(MID$(tempAttrib$(1), testLeft+7))))

testRight = INSTR(tempAttrib$(1), "right of")

If testRighth THEN pos1 = 2: tempAttrib$(1) = LCASE$(LTRIM$(RTRIM$(MID$(tempAttrib$(1), testRight+7))))

testNextTo = INSTR(tempAttrib$(1), "next to")

If testNextTo THEN pos1 = 3: tempAttrib$(1) = LCASE$(LTRIM$(RTRIM$(MID$(tempAttrib$(1), testNextTo+7))))

for j = 0 to 1

value = linksTo(findValue(matrixAttrib2$(), tempAttrib$(j), 0, totAttrib-1))

val1(j) = value \ attribpos

val2(j) = value - val1(j)*attribpos

next j

SELECT CASE pos1

CASE 0

FOR k = 0 to attribpos-1

IF k <> val2(0) THEN

matrix(val1(0), k, val1(1), val2(1)) = 0

matrix(val1(1), val2(1), val1(0), k) = 0

'if i = 4 then print logic$(i); val1(1); val2(1); val1(0); k

'if i = 4 then print logic$(i); val1(0); k; val1(1); val2(1)

END IF

NEXT k

FOR k = 0 to attribpos-1

IF k <> val2(1) THEN

matrix(val1(0), val2(0), val1(1), k) = 0

matrix(val1(1), k, val1(0), val2(0)) = 0

END IF

NEXT k

CASE ELSE

FOR k = 0 to attribpos-1

IF k = val2(0) THEN

matrix(val1(0), val2(0), val1(1), val2(1)) = 0

matrix(val1(1), val2(1), val1(0), val2(0)) = 0

END IF

NEXT k

matrixloc(locpos, 0) = val1(0)

matrixloc(locpos, 1) = val2(0)

matrixloc(locpos, 2) = val1(1)

matrixloc(locpos, 3) = val2(1)

matrixloc(locpos, 4) = pos1 - 1

locpos = locpos + 1

matrixloc(locpos, 0) = val1(1)

matrixloc(locpos, 1) = val2(1)

matrixloc(locpos, 2) = val1(0)

matrixloc(locpos, 3) = val2(0)

matrixloc(locpos, 4) = pos1 - 1

locpos = locpos + 1

END SELECT

pos1 = 0

NEXT i

'How the solution is found:

'we go through matrixloc() and filter it through matrix().

'step 1:

'If the location of an attribute is known that has a relative position,

'we can add it to matrix():

'e.x.:

'if brit is next to a red house,

'then if red house position is known,

'we can set all positions except those two or one nearby to false for brit.

'also, if brit position is known,

'we can set all positions except those two or one nearby to false for red house.

'We go through all of the outstanding relative position truths this way.

'

'step 2:

'then, we go through matrix() and check for all but one conditions

'being false on some attribute and set that one to true.

'Then we go back to step 1 until we know who the fish belongs to.

'(or, alternatively, that there are no unknowns)

do

ex1 = 0

FOR i = 0 to locpos - 1

for j = 0 to 1

IF matrixloc(i, 5+j) = 0 THEN

'check whether attribute 1 position is known.

'To do that, we check whether all other attributes are false.

temp1 = 0

for k = 0 to attribpos-1

IF matrix(matrixloc(i, j+j), matrixloc(i, 1+j+j), 5, k) = 1 THEN temp2 = k: temp1 = temp1 + 1

next k

IF temp1 = 1 THEN

ex1 = 1

'make non-adjacent values equal to 0...

'e.g. if house red = brit,

'set house red <> swede, house red <> german, etc.

'(the mirror value is set in the next pass of 'j', I think..)

'matrixloc(i, 4): 0 = left, 1 = right, 2 = next to.

setNonAdjacentValuesToZero matrix(), matrixloc(), i, j*2, (1-j)*2, matrix(5, k, matrixloc(i, j+j), matrixloc(i, 1+j+j))

matrixloc(i, 5+j) = 1

END IF

END IF

NEXT j

NEXT i

'Inheritance:

'If green <> white and green = coffee, then coffee <> white.

for i = 0 to attrib-1

for j = 0 to attribpos-1

'if [some attribute] <> [some other attribute]...

'and [some attribute] def.= [another attribute]...

'then [some attribute] <> [another attribute].

for k = 0 to attrib-1

for m = 0 to attribpos-1

if i * attribpos + j <> k * attribpos + m then

if matrix(i, j, k, m) = 0 THEN

for n = 0 to attrib-1

temp1 = 0

for o = 0 to attribpos-1

if matrix(i, j, n, o) = 1 then temp2 = o: temp1 = temp1 + 1

NEXT o

if i * attribpos + j <> n * attribpos + temp2 then

if k * attribpos + m <> n * attribpos + temp2 then

IF temp1 = 1 THEN

if matrix(n, temp2, k, m) <> 0 THEN

matrix(n, temp2, k, m) = 0

matrix(k, m, n, temp2) = 0

ex1 = 1

end if

end if

END IF

END IF

NEXT n

END IF

END IF

next m, k, j, i

'Inheritance2:

'if coffee = german and german = red, then coffee = red.

for i = 0 to attrib-1

for j = 0 to attribpos-1

for k = 0 to attrib-1

temp1 = 0

for m = 0 to attribpos-1

temp1 = matrix(i, j, k, m)

if matrix(i, j, k, m) = 1 THEN temp3 = o: temp1 = temp1 + 1

next m

if i * attribpos + j <> k * attribpos + temp3 then

if temp1 = 1 then

for n = 0 to attrib-1

temp1 = 0

for o = 0 to attribpos-1

if matrix(i, j, n, o) = 1 then temp2 = o: temp1 = temp1 + 1

NEXT o

if i * attribpos + j <> n * attribpos + temp2 then

if k * attribpos + temp3 <> n * attribpos + temp2 then

IF temp1 = 1 THEN

if matrix(k, temp3, n, temp2) <> 0 THEN

matrix(k, temp3, n, temp2) = 0

matrix(n, temp2, k, temp3) = 0

ex1 = 1

end if

end if

END IF

END IF

NEXT n

END IF

END IF

next k, j, i

if ex1 = 0 then exit do

loop

for i = 0 to attrib-1

for j = 0 to attribpos-1

for k = 0 to attrib-1

for m = 0 to attribpos-1

IF matrixAttrib$(i * attribpos + j) = "center" THEN

IF matrix(i, j, k, m) = 0 THEN PRINT matrixAttrib$(i * attribpos + j); " <> " ; matrixAttrib$(k * attribpos + m); i ; j ; k; m

END IF

next m, k, j, i

for i = 0 to attrib-1

for j = 0 to attribpos-1

for k = 5 to 5

temp1 = 0

for m = 0 to attribpos-1

if matrix(i, j, k, m) = 1 then temp2 = m: temp1 = temp1 + 1

next m

if temp1 = 1 then

matrixSolution(i, j) = k*attribpos + temp2

else

matrixSolution(i, j) = -1

end if

next k, j, i

print

for i = 0 to attrib-1

for j = 0 to attribpos-1

if matrixSolution(i, j) <> -1 then

PRINT matrixAttrib$(i * attribpos + j);" - ";matrixAttrib$(matrixSolution(i,j))

end if

next i, j

sleep

system

SUB setNonAdjacentValuesToZero (matrix() AS BYTE, matrixloc() AS BYTE, i, j1, j2, position AS BYTE)

leftadj = position - 1

rightadj = position + 1

FOR x = 0 to attribpos-1

SELECT CASE matrixloc(i, 4)

CASE 0: IF x = leftadj THEN GOTO nextfor

CASE 1: IF x = rightadj THEN GOTO nextfor

CASE 2: IF x = leftadj OR x = rightadj THEN GOTO nextfor

END SELECT

matrix(5, x, matrixloc(i, j2), matrixloc(i, j2+1)) = 0

matrix(matrixloc(i, j2), matrixloc(i, j2+1), 5, x) = 0

nextfor:

NEXT x

END SUB

FUNCTION findValue(ats() AS STRING, vtf AS STRING, a AS INTEGER, b AS INTEGER) AS INTEGER

DO

IF a > b then exit do

n = (a + b) / 2

IF vtf = ats(n) THEN findValue = n: EXIT FUNCTION

IF vtf < ats(n) THEN

b = n - 1

ELSE

a = n + 1

END IF

LOOP

findValue = -1

END FUNCTION

SUB qsort.linked.string.lowstart (array1() AS STRING, array2() AS INTEGER, amax AS INTEGER)

DIM g2(0 TO amax) AS INTEGER, h2(0 TO amax) AS INTEGER, i AS INTEGER, j AS INTEGER, r AS INTEGER, E AS INTEGER, g AS INTEGER, h AS INTEGER, k AS STRING

E = 0: g2(0) = 0: h2(0) = amax

e1: g = g2(E): h = h2(E)

e2: i = g: j = h: r = (g + h) \ 2: k = array1(r)

e3: IF array1(i) < k THEN i = i + 1: GOTO e3

e4: IF array1(j) > k THEN j = j - 1: GOTO e4

IF i <= j THEN SWAP array1(i), array1(j): SWAP array2(i), array2(j): i = i + 1: j = j - 1: IF i <= j THEN GOTO e3

IF j - g + i < h THEN

IF i < h THEN g2(E) = i: h2(E) = h: E = E + 1

h = j

ELSE

IF g < j THEN g2(E) = g: h2(E) = j: E = E + 1

g = i

END IF

IF g < h THEN GOTO e2 ELSE E = E - 1: IF E >-1 THEN GOTO e1

ERASE g2, h2

END SUB