Last active
October 30, 2016 05:53
-
-
Save vincentbernat/6959f788d61eb87ca3e4dcd9d9731f28 to your computer and use it in GitHub Desktop.
Network model using Prolog
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% -*- prolog -*- | |
%% Constants | |
nb_aggrs(2). % Number of aggregation switches. | |
nb_racks(3). % Number of racks. | |
nb_hosts(4). % Number of hosts per racks | |
nb_tors(2). % Number of ToR swtches. | |
%% Hard coded failures. | |
% aggr(1) :- !, fail. | |
% tor(1,2) :- !, fail. | |
% link(tor(1,1), aggr(1)) :- !, fail. | |
%% Entities | |
% An aggregation switch. | |
aggr(X) :- nb_aggrs(N), between(1, N, X). | |
% A rack. | |
rack(X) :- nb_racks(N), between(1, N, X). | |
% A host in a rack. | |
host(X, R) :- nb_hosts(N), rack(R), between(1, N, X). | |
% A ToR switch in a rack. | |
tor(X, R) :- nb_tors(N), rack(R), between(1, N, X). | |
%% Physical links | |
% From host to ToR. Each host has a link to each ToR. | |
link(host(X, R), tor(Y, R)) :- rack(R), host(X, R), tor(Y, R). | |
% From ToR to ToR (assuming a mesh). | |
link(tor(X, R), tor(Y, R)) :- rack(R), host(X, R), tor(Y, R). | |
% From ToR to aggreg. In our case, we assume a ToR is linked only to | |
% the matching aggregation switch, not to all of them. | |
link(tor(X, R), aggr(X)) :- rack(R), tor(X, R), aggr(X). | |
%% VLAN | |
% From host to ToR. | |
vlan(Z, host(X, R), tor(Y, R)) :- link(host(X, R), tor(Y, R)), | |
nb_tors(N), | |
MIN is 190 + (Y-1)*N + 1, MAX is 190 + Y*N, between(MIN, MAX, Z). | |
% From ToR to ToR | |
vlan(Z, tor(X, R), tor(Y, R)) :- link(tor(X, R), tor(Y, R)), % X < Y | |
nb_tors(N), | |
Z is 190 + (X-1) * N + (Y - X) + 1. | |
vlan(Z, tor(X, R), tor(Y, R)) :- link(tor(X, R), tor(Y, R)), % X < Y | |
nb_tors(N), | |
Z is 190 + (Y-1) * N + (Y - X) + 1. | |
% From ToR to aggregation. First, the VLAN comes from an host and is not redirected to another ToR. | |
vlan(Z, tor(X, R), aggr(Y)) :- link(tor(X, R), aggr(Y)), | |
vlan(Z, host(_, R), tor(X, R)), | |
nb_tors(N), | |
Z is 190 + (Y-1)*N + 1. | |
% From ToR to aggregayion. Second, the VLAN comes from an host not on this ToR but redirected here. | |
vlan(Z, tor(X, R), aggr(Y)) :- link(tor(X, R), aggr(Y)), | |
vlan(Z, host(_, R), tor(W, R)), | |
W \= X, | |
nb_tors(N), | |
\+Z is 190 + (W-1)*N + 1. | |
%% Router declaration. Routers are host that can route from one VLAN | |
%% to another. Currently, our aggregation switches are also routers. | |
router(aggr(X)) :- aggr(X). | |
%% Reachability (we need to not visit a node twice). | |
l1_connected(X, Y) :- link(X, Y). | |
l1_connected(X, Y) :- link(Y, X). | |
l1_path(X, Y, [X, Y]) :- l1_connected(X, Y). | |
l2_connected(Vlan, X, Y) :- vlan(Vlan, X, Y). | |
l2_connected(Vlan, X, Y) :- vlan(Vlan, Y, X). | |
l2_rpath(X, Y, Vlan, Visited, [Y|Visited]) :- l2_connected(Vlan, X, Y). | |
l2_rpath(X, Y, Vlan, Visited, Path) :- l2_connected(Vlan, X, W), | |
W \== Y, | |
\+member(W, Visited), | |
l2_rpath(W, Y, Vlan, [W|Visited], Path). | |
l2_vpath(X, Y, Vlan, Path) :- l2_rpath(X, Y, Vlan, [X], Q), | |
reverse(Q, Path). | |
l2_path(X, Y, Path) :- l2_vpath(X, Y, _, Path). | |
l2_paths(X, Y, Paths) :- setof(P, l2_path(X, Y, P), Paths). | |
l3_path(host(X, R1), host(Y, R2), Path) :- host(X, R1), host(Y, R2), | |
l3_mixed_path(host(X, R1), host(Y, R2), [], Path). | |
l3_mixed_path(X, Y, _, [P]) :- l2_path(X, Y, P). | |
l3_mixed_path(X, Y, Visited, [L2Path|L3Path]) :- router(W), | |
l2_path(X, W, L2Path), | |
\+member(W, Visited), | |
l3_mixed_path(W, Y, [W|Visited], L3Path). | |
% Example: | |
% use_module(library(pprint)). | |
% l2_paths(host(1,1), host(1, 2), P), print_term(P, []). | |
%% TODO | |
% - loop-free L3 | |
% - fault logic |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment