Skip to content

Instantly share code, notes, and snippets.

@adicuco
Created January 22, 2020 16:37
Show Gist options
  • Save adicuco/b4ede38b97b43a01d9fe1408215deafb to your computer and use it in GitHub Desktop.
Save adicuco/b4ede38b97b43a01d9fe1408215deafb to your computer and use it in GitHub Desktop.
% vehicle facts
vehicle(bicycle).
vehicle(car).
vehicle(taxi) :-
vehicle(car).
vehicle(bus).
distinct(bicycle, taxi).
distinct(bicycle, car).
distinct(bicycle, bus).
distinct(bus, car).
distinct(bus, taxi).
max_travellers(bus, 20).
max_travellers(car, 4).
max_travellers(taxi, 4).
max_travellers(bicycle, 1).
% traveller facts
traveller(dwight, bus).
traveller(dwight, bicycle).
traveller(dwight, car).
traveller(dwight, taxi).
traveller(michael, bicycle).
traveller(michael, taxi).
traveller(michael, car).
traveller(michael, bus).
traveller(jim, bus).
traveller(jim, taxi).
traveller(jim, car).
traveller(kevin, bus).
traveller(pam, car).
traveller(pam, taxi).
traveller(oscar, bicycle).
traveller(oscar, bus).
traveller(ryan, bicycle).
traveller(erin, taxi).
traveller(creed, bus).
% town facts
town(bucharest).
town(constanta).
town(vama_veche).
town(ploiesti).
town(ciolpani).
town(predeal).
town(brasov).
town(rasnov).
town(bran).
town(moeciu).
% road facts
road_condition(motorway).
road_condition(paved_street).
road_condition(gravel_road).
road(bucharest, constanta, 225, 2.5, motorway).
road(constanta, vama_veche, 55, 0.9, paved_street).
road(bucharest, ploiesti, 80, 1.1, motorway).
road(bucharest, ciolpani, 30, 0.55, paved_street).
road(ciolpani, ploiesti, 35, 0.6, paved_street).
road(ploiesti, predeal, 65, 1.3, paved_street).
road(predeal, brasov, 50, 0.7, motorway).
road(predeal, rasnov, 20, 0.6, gravel_road).
road(rasnov, brasov, 20, 0.4, paved_street).
road(rasnov, bran, 11, 0.2, paved_street).
road(bran, moeciu, 9, 0.4, gravel_road).
% road rules
% connection - make the road traversable both ways
connection(From, To, Distance, Time, Road_Condition) :-
( road(From, To, Distance, Time, Road_Condition)
; road(To, From, Distance, Time, Road_Condition)
).
% can_use_road - enforces what type of vehicle can travel on the road based on its conditions
can_use_road(From, To, Vehicle) :-
( Vehicle==car,
connection(From, To, _, _, motorway)
; Vehicle==car,
connection(From, To, _, _, paved_street)
; Vehicle==car,
connection(From, To, _, _, gravel_road)
; Vehicle==taxi,
connection(From, To, _, _, motorway)
; Vehicle==taxi,
connection(From, To, _, _, paved_street)
; Vehicle==taxi,
connection(From, To, _, _, gravel_road)
; Vehicle==bus,
connection(From, To, _, _, motorway)
; Vehicle==bus,
connection(From, To, _, _, paved_street)
; Vehicle==bicycle,
connection(From, To, _, _, paved_street)
; Vehicle==bicycle,
connection(From, To, _, _, gravel_road)
).
% path - creates a path between 2 towns
path(From, To, Path, Distance, Time, Vehicle) :-
findpath(From,
To,
[From],
Visited,
Distance,
Time,
Vehicle),
reverse(Visited, Path).
% findpath - helper function for creating the path
% - a path can either be a direct connecton between 2 towns
% - or can consist of more linked connections
findpath(From, To, Path, [To|Path], Distance, Time, Vehicle) :-
connection(From, To, Distance, Time, _),
can_use_road(To, From, Vehicle).
findpath(From, To, Visited, Path, Distance, Time, Vehicle) :-
connection(From, Link, D1, T1, _),
can_use_road(From, Link, Vehicle),
Link\==To,
\+ member(Link, Visited),
findpath(Link,
To,
[Link|Visited],
Path,
D2,
T2,
Vehicle),
Distance is D1+D2,
Time is T1+T2.
% shortest - compute the shortest route between 2 towns
% - regardless of the traveller
shortest(X, X, [X, X], 0) :-
!.
shortest(From, To, Path, Distance, Vehicle) :-
findall([D, P],
path(From,
To,
P,
D,
_,
Vehicle),
Set),
sort(Set, Sorted),
Sorted=[[Distance, Path]|_].
% fastest - compute the fastest route between 2 towns
% - regardless of the traveller
fastest(X, X, [X, X], 0) :-
!.
fastest(From, To, Path, Time, Vehicle) :-
findall([T, P],
path(From,
To,
P,
_,
T,
Vehicle),
Set),
sort(Set, Sorted),
Sorted=[[Time, Path]|_].
% len - helper function to compute the length of a list
len([], Length) :-
Length is 0.
len([_|Y], Length) :-
len(Y, L),
Length is L+1.
% travel - computes the Path for a traveller or a list of travellers
% - who travels between 2 towns
travel(_, _, _, [], _).
travel(From, To, Path, Traveller, Vehicle) :-
traveller(Traveller, Vehicle),
path(From, To, Path, _, _, Vehicle).
travel(From, To, Path, [Traveller|Rest], Vehicle) :-
max_travellers(Vehicle, Max),
len([Traveller|Rest], Length),
Length=<Max,
travel(From, To, Path, Traveller, Vehicle),
travel(From, To, Path, Rest, Vehicle).
% can_travel - answers if a traveller of a list of travellers
% - can travel between 2 towns
can_travel(From, To, Travellers) :-
travel(From, To, _, Travellers, _).
% can_travel_with - answers what vehicles can be used by a traveller
% - or a list of travellers to travel between 2 towns
can_travel_with(From, To, Travellers, Vehicles) :-
findall(V,
travel(From, To, _, Travellers, V),
Set),
sort(Set, Vehicles).
% get_shortest - computes the shortest path for a traveller between 2 towns
get_shortest(From, To, Path, Distance, Traveller, Vehicle) :-
traveller(Traveller, Vehicle),
shortest(From, To, Path, Distance, Vehicle).
% get_fastest - computes the fastest path for a traveller between 2 towns
get_fastest(From, To, Path, Time, Traveller, Vehicle) :-
traveller(Traveller, Vehicle),
fastest(From, To, Path, Time, Vehicle).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment