Skip to content

Instantly share code, notes, and snippets.

@vincentbernat
Last active October 30, 2016 05:53
Show Gist options
  • Save vincentbernat/6959f788d61eb87ca3e4dcd9d9731f28 to your computer and use it in GitHub Desktop.
Save vincentbernat/6959f788d61eb87ca3e4dcd9d9731f28 to your computer and use it in GitHub Desktop.
Network model using Prolog
% -*- 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