1:- module(nanp, [invalid/1, valid/1, format/3]). 2:- use_module(library(clpfd)).
nanp(Area,Office,Subscriber)
.8valid(nanp(Area,Office,Subscriber)) :- 9 valid_area_code(Area,_,_,_), 10 valid_office_code(Office,_,_,_), 11 valid_subscriber_code(Subscriber,_,_,_,_). 12 13% see http://www.nanpa.com/area_codes/index.html for rules 14valid_area_code(NXX,N,X1,X2) :- 15 NXX in 200..999, 16 N in 2..9, 17 X1 in 0..8, % 9 is prohibited until a theoretical, future expansion 18 X2 in 0..9, 19 NXX #= 100*N + 10*X1 + X2, 20 N #= 3 #==> X1 #\= 7, 21 N #= 9 #==> X1 #\= 6. 22 23% see http://www.nanpa.com/number_resource_info/co_codes.html for rules 24valid_office_code(NXX,N,X1,X2) :- 25 NXX in 200..999, 26 N in 2..9, 27 [X1,X2] ins 0..9, 28 NXX #= 100*N + 10*X1 + X2, 29 X1 #= 1 #==> X2 #\= 1. 30 31valid_subscriber_code(S,A,B,C,D) :- 32 S in 0..9999, 33 [A,B,C,D] ins 0..9, 34 S #= 1000*A + 100*B + 10*C + D. 35 36% easily recognizable code 37erc(NXX) :- 38 valid_area_code(NXX,_,X,X). 39 40% N11 codes 41n11(NXX) :- 42 valid_office_code(NXX,_,1,1).
nanp(Area,Office,Subscriber)
.
49invalid(Number) :-
50 \+ valid(Number).
e_164
- E.164 (like "+17606668462")dial(us)
- how to dial from inside the US (like "1-760-666-8462")ten_digit
- local, ten-digit dialing (like "760-666-8462")traditional
- traditional American format (like "(760) 666-8462")uri
- as a URI (like "tel:+17606668462")This predicate may be used for parsing and formatting telephone numbers.
66format(Format,Number,Codes) :- 67 phrase(format(Format,Number),Codes). 68 69format(e_164,nanp(A,O,S)) --> % https://en.wikipedia.org/wiki/E.164 70 "+1", 71 area_code(A), 72 office_code(O), 73 subscriber_code(S). 74format(dial(us),Number) --> % format describes dialing a number from US 75 "1-", 76 format(ten_digit,Number). 77format(ten_digit,nanp(A,O,S)) --> 78 area_code(A), 79 "-", 80 office_code(O), 81 "-", 82 subscriber_code(S). 83format(traditional,nanp(A,O,S)) --> % http://goo.gl/kkHkZY 84 "(", 85 area_code(A), 86 ") ", 87 office_code(O), 88 "-", 89 subscriber_code(S). 90format(uri,Number) --> 91 "tel:", 92 format(e_164,Number). 93 94area_code(A) --> 95 { valid_area_code(A,N,X1,X2) }, 96 digit(N), 97 digit(X1), 98 digit(X2). 99 100office_code(O) --> 101 { valid_office_code(O,N,X1,X2) }, 102 digit(N), 103 digit(X1), 104 digit(X2). 105 106subscriber_code(S) --> 107 { valid_subscriber_code(S,A,B,C,D) }, 108 digit(A), 109 digit(B), 110 digit(C), 111 digit(D). 112 113digit(N) --> 114 [C], 115 { digit_char(N,C) }. 116 117digit_char(0,0'0). 118digit_char(1,0'1). 119digit_char(2,0'2). 120digit_char(3,0'3). 121digit_char(4,0'4). 122digit_char(5,0'5). 123digit_char(6,0'6). 124digit_char(7,0'7). 125digit_char(8,0'8). 126digit_char(9,0'9)