% vim: syntax=prolog :- use_module(library(clpfd)). :- use_module(library(dcg/basics)). ip4(A, B, C, D, Addr) :- A in 0..255, B in 0..255, C in 0..255, D in 0..255, Addr #= (A * 2^24 + B * 2^16 + C * 2^8 + D). ip4_range(ip4(_, _, _, _), Range) :- Range in 0..32. ip_format(ip4(A, B, C, D, _), Str) :- format(string(Str), "~w.~w.~w.~w", [A, B, C, D]). ip_format(ip4_range(ip4(A, B, C, D, _), Range), Str) :- format(string(Str), "~w.~w.~w.~w/~w", [A, B, C, D, Range]). ip4_g(A, B, C, D) --> ip4_num(A), ".", ip4_num(B), ".", ip4_num(C), ".", ip4_num(D). ip4_num(D) --> integer(D), { D >= 0, D =< 255 }. ipx(A) --> integer(A). ip_parse(Str, Obj) :- string_codes(Str, Codes), phrase(ip4_g(A, B, C, D), Codes), Obj = ip4(A, B, C, D). :- begin_tests(lists). :- use_module(library(lists)). test(ip4) :- ip4(127, 0, 0, 1, A), assertion(A =:= (127 * 2**24 + 1)). test(ip_format) :- ip_format(ip4(127, 0, 0, 1, _), Str), assertion(Str == "127.0.0.1"). test(ip_format) :- Ip = ip4_range(ip4(192, 168, 0, 0, _), 24), ip_format(Ip, Str), assertion(Str == "192.168.0.0/24"). test(ip_parse) :- ip_parse("1.2.3.4", Ip), assertion(Ip == ip4(1, 2, 3, 4)). :- end_tests(lists).