summaryrefslogtreecommitdiff
path: root/lab3/lab3.py
blob: bb41579c519a64d6050ebea4705ab44ad5c488bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
import numpy as np

#####################
# Бинарные операции #
#####################

def check_associativity(cayley: np.array, elements: list) -> bool:
    n = cayley.shape[0]
    for i in range(n):
        for j in range(n):
            for k in range(n):
                q = elements.index(cayley[i, k])
                p = elements.index(cayley[j, i])
                if cayley[p, k] != cayley[j, q]:
                    return False
    return True


def check_commutativity(cayley: np.array, elements: list) -> bool:
    n = cayley.shape[0]
    for i in range(n):
        for j in range(n):
            if cayley[i, j] != cayley[j, i]:
                return False
    return True


def check_idempotence(cayley: np.array, elements: list) -> bool:
    n = cayley.shape[0]
    for i in range(n):
        a = elements[i]
        if cayley[i, i] != a:
            return False
    return True


def check_reversibility(cayley: np.array, elements: list) -> bool:
    n = cayley.shape[0]
    for i in range(n):
        for j in range(n):
            if cayley[i, j] != 1 or cayley[j, i] != 1:
                return False
    return True


# cayley1 - *, cayley2 - +
def check_distributivity(cayley1: np.array, cayley2: np.array, elements: list) -> bool:
    n = cayley1.shape[0]
    for i in range(n):
        for j in range(n):
            for k in range(n):
                t = elements.index(cayley2[j, k])
                p = elements.index(cayley1[i, j])
                q = elements.index(cayley1[i, k])
                r = elements.index(cayley1[j, i])
                s = elements.index(cayley1[k, i])
                if cayley1[i, t] != cayley2[p, q] or \
                    cayley1[t, i] != cayley2[r, s]:
                    return False
    return True


def check_operation():
    print("Введите элементы множества, на котором определена операция:")
    elements = input().strip().split()
    n = len(elements)
    print("Введите таблицу Кэли:")
    cayley = []
    for i in range(n):
        line = input().strip().split()
        cayley.append(line)
    cayley = np.array(cayley, dtype=str)

    status = []

    if check_associativity(cayley, elements):
        status.append("ассоциативность")
    if check_commutativity(cayley, elements):
        status.append("коммутативность")
    if check_idempotence(cayley, elements):
        status.append("идемпотентность")
    if check_reversibility(cayley, elements):
        status.append("обратимость")
    
    flag = input("Проверить на дистрибутивность? (да/НЕТ) ")
    if flag.lower() == "да":
        print("Введите таблицу Кэли второй операции:")
        cayley2 = []
        for i in range(n):
            line = input().strip().split()
            cayley2.append(line)
        cayley2 = np.array(cayley2, dtype=str)
        if check_distributivity(cayley, cayley2, elements):
            status.append("дистрибутивность")
    
    if status:
        print("Заданная бинарная операция обладает следующими свойствами:")
        for i in status:
            print(i)
    else:
        print("Заданная бинарная операция не обладает никакими свойствами")


######################
# Бинарные отношения #
######################

def make_union(a: np.array, b: np.array):
    return a + b


def make_intersection(a: np.array, b: np.array):
    return np.multiply(a, b)


def make_complement(m: np.array):
    return 1 - m


def make_reverse(m: np.array):
    return np.transpose(m)


def make_composition(a: np.array, b: np.array):
    return np.matmul(a, b)


def check_relations():
    def read_array(n: int) -> np.array:
        a = []
        for _ in range(n):
            line = list(map(int, input().strip().split()))
            a.append(line)
        return np.array(a, dtype=bool)

    n = int(input("Введите размерность проверяемых отношений: "))

    print("Введите бинарное отношение A:")
    a = read_array(n)
    print("Введите бинарное отношение B:")
    b = read_array(n)

    print("Объединение бинарных отношений:")
    print((a + b).astype(int))

    print("Пересечение бинарных отношений:")
    print(np.multiply(a, b).astype(int))

    print("Дополнение бинарного отношения A:")
    print((1 - a).astype(int))

    print("Дополнение бинарного отношения B:")
    print((1 - b).astype(int))

    print("Бинарное отношение, обратное A:")
    print(np.transpose(a).astype(int))

    print("Бинарное отношение, обратное B:")
    print(np.transpose(b).astype(int))

    print("Композиция отношений:")
    print(np.matmul(a, b).astype(int))

########################
# Операции с матрицами #
########################

def mat_add(a: np.array, b: np.array):
    return a + b


def mat_scale(m: np.array, alpha: float):
    return alpha * m


def mat_transpose(m: np.array):
    return np.transpose(m)


def mat_multiply(a: np.array, b: np.array):
    return np.matmul(a, b)


def check_matrices():
    def read_matrix(n: int, m: int) -> np.array:
        a = []
        for _ in range(n):
            line = list(map(float, input().strip().split()))
            a.append(line)
        return np.array(a, dtype=float)

    print("1 - Сложение матриц;")
    print("2 - Умножение матрицы на скаляр;")
    print("3 - Транспонирование матриц;")
    print("4 - Умножение матриц;")
    test = int(input("> "))
    if test == 1:
        n, m = map(int, input("Введите размерность матриц: ").split())
        print("Введите матрицу A:")
        a = read_matrix(n, m)

        print("Введите матрицу B:")
        b = read_matrix(n, m)

        print("Сумма матриц:")
        print(mat_add(a, b))
    elif test == 2:
        n, m = map(int, input("Введите размерность матрицы: ").split())
        print("Введите матрицу:")
        a = read_matrix(n, m)

        alpha = float(input("Введите скаляр: "))

        print("Результат:")
        print(mat_scale(a, alpha))
    elif test == 3:
        n, m = map(int, input("Введите размерность матрицы: ").split())
        print("Введите матрицу:")
        a = read_matrix(n, m)

        print("Результат:")
        print(mat_transpose(a))
    elif test == 4:
        n, m = map(int, input("Введите размерность матрицы A: ").split())
        print("Введите матрицу A:")
        a = read_matrix(n, m)

        n, m = map(int, input("Введите размерность матрицы B: ").split())
        print("Введите матрицу B:")
        b = read_matrix(n, m)

        print("Произведение матриц:")
        print(mat_multiply(a, b))

############
# Задача 1 #
############

def task1():
    print("Задача 1:")
    elements = "a b c d".split()
    cayley = np.array([
        list("abab"),
        list("abab"),
        list("abcd"),
        list("abcd"),
    ])
    if check_associativity(cayley, elements):
        print("Данная операция является ассоциативной")
    else:
        print("Данная операция не является ассоциативной")

############
# Задача 2 #
############

def task2(l: float):
    print("Задача 2:")
    a = np.array([
        [1, -2],
        [-3, l]
    ])
    e = np.identity(2)
    b = mat_add(
        mat_add( mat_multiply(a, a), 
                 mat_scale(10 - l / 2, a) ), 
        mat_scale(l / 2, e)
    )
    print(b)

############
# Задача 3 #
############

def task3(l: float):
    print("Задача 3:")
    a = np.array([
        [   -1, l,         3],
        [l / 3, 2, 8 - l / 3]
    ])
    b = np.array([
        [-l,          2],
        [ 1, 10 - l / 2],
        [-3,          l]
    ])
    print(mat_multiply(a, b))

############

def main():
    flag = input("Проверить свойства бинарных операций? (да/НЕТ) ")
    if flag.lower() == "да":
        check_operation()

    flag = input("Проверить операции с бинарными отношениями? (да/НЕТ) ")
    if flag.lower() == "да":
        check_relations()

    flag = input("Проверить операции с матрицами? (да/НЕТ) ")
    if flag.lower() == "да":
        check_matrices()

    flag = input("Выполнить задания? (да/НЕТ) ")
    if flag.lower() == "да":
        l = 6
        task1()
        task2(l)
        task3(l)


if __name__ == "__main__":
    main()